package cn.lili.modules.order.order.serviceimpl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import cn.lili.cache.Cache;
import cn.lili.cache.LockPrefix;
import cn.lili.common.enums.PromotionTypeEnum;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.event.TransactionCommitSendMQEvent;
import cn.lili.common.exception.ServiceException;
import cn.lili.common.security.AuthUser;
import cn.lili.common.security.context.UserContext;
import cn.lili.common.security.enums.PayWayEnum;
import cn.lili.common.security.enums.SceneEnums;
import cn.lili.common.security.enums.VipStatusEnum;
import cn.lili.common.thread.ThreadConfig;
import cn.lili.common.utils.CurrencyUtil;
import cn.lili.common.utils.ResultUtil;
import cn.lili.common.utils.SnowFlake;
import cn.lili.common.utils.StringUtils;
import cn.lili.common.vo.ResponseBean;
import cn.lili.common.vo.ResultMessage;
import cn.lili.exchange.AmqpExchangeProperties;
import cn.lili.lililogs.logs.annotation.SystemLogPoint;
import cn.lili.modules.constant.CommonConstant;
import cn.lili.modules.distribution.client.DistributionClient;
import cn.lili.modules.distribution.entity.dos.Distribution;
import cn.lili.modules.distribution.entity.enums.DistributionStatusEnum;
import cn.lili.modules.distribution.entity.vos.DistributionOrderSearchParams;
import cn.lili.modules.distribution.entity.vos.HomeResult;
import cn.lili.modules.goods.client.CategoryClient;
import cn.lili.modules.goods.client.GoodsClient;
import cn.lili.modules.goods.client.GoodsSkuClient;
import cn.lili.modules.goods.client.GrabOrderClient;
import cn.lili.modules.goods.entity.dos.Goods;
import cn.lili.modules.goods.entity.dos.GoodsSku;
import cn.lili.modules.goods.entity.dto.GoodsCompleteMessage;
import cn.lili.modules.goods.entity.dto.GoodsSearchParams;
import cn.lili.modules.goods.entity.vos.yunxin.*;
import cn.lili.modules.grab.GrabOrderParam;
import cn.lili.modules.member.client.CityDistributionClient;
import cn.lili.modules.member.client.UserClient;
import cn.lili.modules.member.client.VipClient;
import cn.lili.modules.member.entity.dos.CityDistribution;
import cn.lili.modules.member.entity.dos.User;
import cn.lili.modules.member.entity.dto.CityDistributionDTO;
import cn.lili.modules.member.entity.dto.MemberAddressDTO;
import cn.lili.modules.member.entity.enums.ComissStatusEnum;
import cn.lili.modules.member.entity.vo.CityDistributionVO;
import cn.lili.modules.operationcenter.client.OperationCenterClient;
import cn.lili.modules.operationcenter.entity.dos.OperationCenter;
import cn.lili.modules.order.aftersale.entity.dos.AfterSale;
import cn.lili.modules.order.aftersale.service.AfterSaleService;
import cn.lili.modules.order.build.ComputeDTO;
import cn.lili.modules.order.build.OrderComputeEventFactory;
import cn.lili.modules.order.cart.entity.dto.TradeDTO;
import cn.lili.modules.order.cart.entity.vo.CartSkuVO;
import cn.lili.modules.order.cart.entity.vo.CartVO;
import cn.lili.modules.order.order.aop.OrderLogPoint;
import cn.lili.modules.order.order.callback.OrderFactory;
import cn.lili.modules.order.order.entity.constant.FreeWarehouseConstant;
import cn.lili.modules.order.order.entity.dos.*;
import cn.lili.modules.order.order.entity.dto.*;
import cn.lili.modules.order.order.entity.enums.*;
import cn.lili.modules.order.order.entity.params.DataStatisticsTableVO;
import cn.lili.modules.order.order.entity.params.DirectPushOrderParams;
import cn.lili.modules.order.order.entity.vo.*;
import cn.lili.modules.order.order.entity.vo.warehouse.InterceptReq;
import cn.lili.modules.order.order.manage.OrderManage;
import cn.lili.modules.order.order.mapper.OrderMapper;
import cn.lili.modules.order.order.service.*;
import cn.lili.modules.order.trade.entity.dos.OrderLog;
import cn.lili.modules.order.trade.entity.enums.AfterSaleStatusEnum;
import cn.lili.modules.order.trade.entity.enums.AfterSaleTypeEnum;
import cn.lili.modules.payment.client.PaymentClient;
import cn.lili.modules.payment.entity.dos.PaymentLog;
import cn.lili.modules.payment.entity.enums.PaymentMethodEnum;
import cn.lili.modules.promotion.client.*;
import cn.lili.modules.promotion.entity.dos.BlindboxRuleOrder;
import cn.lili.modules.promotion.entity.dos.Pintuan;
import cn.lili.modules.promotion.entity.dos.Ticket;
import cn.lili.modules.promotion.entity.dos.TicketOrder;
import cn.lili.modules.promotion.entity.dto.CallbackBlindboxDTO;
import cn.lili.modules.promotion.entity.enums.GreenAmountInfoStatusEnum;
import cn.lili.modules.promotion.entity.enums.TicketOrderStatusEnum;
import cn.lili.modules.promotion.entity.enums.TicketSaleStateEnum;
import cn.lili.modules.promotion.entity.vos.TicketAddVO;
import cn.lili.modules.store.client.StoreClient;
import cn.lili.modules.store.entity.dos.Store;
import cn.lili.modules.store.entity.dto.StoreSearchParams;
import cn.lili.modules.store.entity.enums.StoreStatusEnum;
import cn.lili.modules.store.entity.params.StoreSaleTopParams;
import cn.lili.modules.store.entity.vos.StoreSaleTopVO;
import cn.lili.modules.store.entity.vos.StoreVO;
import cn.lili.modules.system.client.*;
import cn.lili.modules.system.constants.DictConstant;
import cn.lili.modules.system.entity.dos.Dictionary;
import cn.lili.modules.system.entity.dos.LiVip;
import cn.lili.modules.system.entity.dos.Logistics;
import cn.lili.modules.system.entity.dos.RegionYbj;
import cn.lili.modules.system.entity.enums.SettingEnum;
import cn.lili.modules.system.entity.vo.PackConfigVO;
import cn.lili.modules.system.entity.vo.Traces;
import cn.lili.mybatis.util.PageUtil;
import cn.lili.mybatis.util.SceneHelp;
import cn.lili.routing.GoodsRoutingKey;
import cn.lili.routing.OrderRoutingKey;
import cn.lili.routing.PromotionRoutingKey;
import cn.lili.trigger.enums.DelayTypeEnums;
import cn.lili.trigger.interfaces.TimeTrigger;
import cn.lili.trigger.message.PintuanOrderMessage;
import cn.lili.trigger.model.TimeExecuteConstant;
import cn.lili.trigger.model.TimeTriggerMsg;
import cn.lili.trigger.util.DelayQueueTools;
import cn.lili.util.AmqpMessage;
import cn.lili.util.AmqpSender;
import cn.lili.util.HomeResultUtil;
import cn.lili.util.ToolsUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.api.PayApi;
import com.api.UserApi;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pojos.FyUserInfo;
import com.pojos.OpenAppUser;
import jxl.Workbook;
import jxl.format.UnderlineStyle;
import jxl.write.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;
import org.apache.poi.ss.util.CellRangeAddressList;
import org.apache.shardingsphere.transaction.annotation.ShardingTransactionType;
import org.apache.shardingsphere.transaction.core.TransactionType;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.annotation.Lazy;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.InputStreamResource;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.InputStream;
import java.lang.Boolean;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.YearMonth;
import java.time.ZoneId;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * 子订单业务层实现
 *
 * @author Chopper
 * @since 2020/11/17 7:38 下午
 */
@Service
@RequiredArgsConstructor(onConstructor_= @Lazy)
@Slf4j
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {

    private static final String ORDER_SN_COLUMN = "order_sn";
    /**
     * 延时任务
     */
    private final TimeTrigger timeTrigger;
    /**
     * 订单货物数据层
     */
    private final OrderItemService orderItemService;
    /**
     * 供应链订单异常记录
     */
    private final OrderItemErrorService orderItemErrorService;
    /**
     * 发票
     */
    private final ReceiptService receiptService;
    /**
     * 物流公司
     */
    private final LogisticsClient logisticsClient;
    /**
     * 订单日志
     */
    private final OrderLogService orderLogService;
    /**
     * 订单流水
     */
    private final OrderFlowService orderFlowService;
    /**
     * 售后流水
     */
    private final RefundFlowService refundFlowService;
    /**
     * 拼团
     */
    private final PromotionsClient promotionsClient;

    private final AmqpSender amqpSender;

    private final ApplicationEventPublisher applicationEventPublisher;

    private final AmqpExchangeProperties amqpExchangeProperties;

    private final UserClient userClient;

    private final GoodsClient goodsClient;

    private final GoodsSkuClient goodsSkuClient;

    private final PayApi payApi;

    private final BlindboxCountClient blindboxCountClient;

    private final RedisTemplate redisTemplate;

    private final OrderFactory orderFactory;

    private final GrabOrderClient grabOrderClient;

    private final RedissonClient redisson;

    private final OrderManage orderManage;

    private final ThreadConfig threadConfig;

    private final RegionYbjClient regionYbjClient;

    private final ReturnActivityClient returnActivityClient;

    private final OrderComputeEventFactory orderComputeEventFactory;

    private final StoreClient storeClient;

    private final BoxLotteryTicketClient boxLotteryTicketClient;

    private final RedissonClient redissonClient;

    private final TicketClient ticketClient;

    private final TicketOrderClient ticketOrderClient;

    private final CategoryClient categoryClient;

    private final DictionaryClient dictionaryClient;

    private final BlindboxRelClient blindboxRelClient;

    private final UserApi userApi;
    private final GreenClient greenClient;

    private final IRankingActivityConfigService activityConfigService;

    private final IRankingScoreDetailsService scoreDetailsService;

    private final SettingClient settingClient;

    private final IRankingDistributionService rankingDistributionService;

    private final CityDistributionClient cityDistributionClient;

    @Value("${fw.appid}")
    String appId;

    private final IPaymentCallbackOrderLogService paymentCallbackOrderLogService;

    private final TradeService tradeService;

    private final PaymentClient paymentClient;

    private final AfterSaleService afterSaleService;

    private final Cache cache;

    private final DistributionClient distributionClient;

    private final FirstBuyRecordService firstBuyRecordService;

    private final OperationCenterClient operationCenterClient;

    private final PackConfigClient packConfigClient;

    private final VipClient vipClient;

    private final UserFreetaxOrderYearTotalService userFreetaxOrderYearTotalService;

    private final OrderFreeStatusLogService orderFreeStatusLogService;

    @Override
    @Transactional
    public void intoDB(TradeDTO tradeDTO) {
        //检查TradeDTO信息
        checkTradeDTO(tradeDTO);
        //存放购物车，即业务中的订单
        List<Order> orders = new ArrayList<>(tradeDTO.getCartList().size());
        //存放自订单/订单日志
        List<OrderItem> orderItems = new ArrayList<>();
        List<OrderLog> orderLogs = new ArrayList<>();

        //订单集合
        List<OrderVO> orderVOS = new ArrayList<>();
        //循环购物车
        for (CartVO item : tradeDTO.getCartList()) {
            if (item.getSkuList().stream().noneMatch(CartSkuVO::getChecked)) {
                continue;
            }
            Order order = new Order(item, tradeDTO);
            //构建orderVO对象
            OrderVO orderVO = new OrderVO();
            BeanUtil.copyProperties(order, orderVO);

            if (CharSequenceUtil.isEmpty(order.getDistributionId())) {
                order.setDistributionId(null);
            }

            //持久化DO
            orders.add(order);
            String message = "订单[" + item.getSn() + "]创建";
            //记录日志
            orderLogs.add(new OrderLog(item.getSn(), UserContext.getCurrentUser().getExtendId(),
                    UserContext.getCurrentUser().getScene().value(),
                    UserContext.getCurrentUser().getUsername(), message));
//            item.getCheckedSkuList().forEach(sku -> orderItems.add(new OrderItem(sku, item, tradeDTO)));
            item.getCheckedSkuList().forEach(sku -> {
                OrderItem itemOrder = new OrderItem(sku, item, tradeDTO);
                //创建订单赋值礼包id
                if (sku.getGoodsSku() != null) {
                    Goods goods = goodsClient.getById(sku.getGoodsSku().getGoodsId());
                    //是否一级分销
                    itemOrder.setIsLevelDistribution(goods.getIsLevelDistribution() != null && goods.getIsLevelDistribution());
                    //商品礼包id相关
                    if (goods != null && StrUtil.isNotEmpty(goods.getPackId())) {
                        PackConfigVO packConfigVO = packConfigClient.getById(goods.getPackId());
                        if (packConfigVO != null && packConfigVO.getPackStatus() != null && packConfigVO.getPackStatus() == 1) {
                            itemOrder.setPackId(goods.getPackId());
                            itemOrder.setPackName(packConfigVO.getPackName());
                            itemOrder.setIsDeliver(packConfigVO.getIsDeliver());
                            //无需发货状态
//                            if (!itemOrder.getIsDeliver()) {
//                                orderVO.setDeliverStatus(DeliveryMethodEnum.NOT_LOGISTICS.name());
//                                order.setDeliverStatus(DeliveryMethodEnum.NOT_LOGISTICS.name());
//                            }

                        }
                    }
                    //是否不允许取消:  goods.getIsCancel 是否允许取消,在order里取反:是否不允许取消
                    orderVO.setIsCancel(goods.getIsCancel() != null && !goods.getIsCancel());
                    order.setIsCancel(goods.getIsCancel() != null && !goods.getIsCancel());
                }
                orderItems.add(itemOrder);
            });
            //写入子订单信息
            orderVO.setOrderItems(orderItems);
            //orderVO 记录
            orderVOS.add(orderVO);

            if (null != tradeDTO.getTicketAddVOList() && !tradeDTO.getTicketAddVOList().isEmpty()) {
                saveTicketOrder(tradeDTO, item);
            }
        }
        tradeDTO.setOrderVO(orderVOS);
        //批量保存订单
        this.saveBatch(orders);
        //批量保存 子订单
        orderItemService.saveBatch(orderItems);
        //批量记录订单操作日志
        orderLogService.saveBatch(orderLogs);
    }

    private void saveTicketOrder(TradeDTO tradeDTO, CartVO item) {
        for (TicketAddVO ticketAddVO : tradeDTO.getTicketAddVOList()) {
            RLock rLock = redissonClient.getLock(ticketAddVO.getAreaName()
                    + ticketAddVO.getAreaDirection()
                    + String.valueOf(ticketAddVO.getRowNumbers())
                    + String.valueOf(ticketAddVO.getColumnNumbers()));
            try {
                rLock.lock();
                Ticket ticket = ticketClient.getTicket(ticketAddVO.getAreaName(), ticketAddVO.getAreaDirection(),
                        String.valueOf(ticketAddVO.getRowNumbers()), String.valueOf(ticketAddVO.getColumnNumbers()));
                String msg = ticketAddVO.getAreaName() + "-"
                        + ticketAddVO.getAreaDirection() + "-"
                        + ticketAddVO.getRowNumbers() + "排" + ticketAddVO.getColumnNumbers() + "座";
                if (null == ticket) {
                    throw new ServiceException(msg + "，座位信息不存在，请重新选座");
                }
                if (ticket.getDownState() == 0 || ticket.getDeleteFlag()
                        || TicketSaleStateEnum.LOCKSALE.name().equals(ticket.getSaleState())) {
                    throw new ServiceException(msg + "，座位不可用，请重新选座");
                }
                if (TicketSaleStateEnum.OFFSALE.name().equals(ticket.getSaleState())) {
                    throw new ServiceException(msg + "，座位已售出，请重新选座");
                }
                TicketOrder ticketOrder = new TicketOrder();
                ticketOrder.setOrderNo(SnowFlake.createStr("TK"));
                ticketOrder.setTicket(ticket.getTicket());
                ticketOrder.setTicketId(ticket.getId());
                ticketOrder.setSeat(ticket.getSeat());
                ticketOrder.setTransactionSn(item.getSn());
                ticketOrder.setUserId(UserContext.getCurrentId());
                ticketOrder.setUserName(UserContext.getCurrentUser().getUsername());
                ticketOrder.setPlaceTime(new Date());
                ticketOrder.setOrderStatus(TicketOrderStatusEnum.UNPAID.name());
                List<CartSkuVO> list = item.getCheckedSkuList().stream().filter(sku -> null != sku.getIsMeal() && sku.getIsMeal()).toList();
                ticketOrder.setExchangeType(!list.isEmpty() ? "1" : "0");
                ticketOrderClient.createOrder(ticketOrder);
            }catch (ServiceException e) {
                throw e;
            }finally {
                rLock.unlock();
            }
        }
    }

    @Override
    @Transactional
    public Order payOrder(PaymentLog paymentLog) {
        //获取订单
        Order order = this.getBySn(paymentLog.getOrderSn());

        //修改订单状态
        order.setPaymentTime(new Date());
        order.setPaymentMethod(paymentLog.getPaymentMethod());

        PriceDetailDTO model = PriceDetailDTO.getModel(order.getPriceDetail());
        log.info("#payOrder# model.getFmoney:" + model.getFmoney());
        Double fMoney = model.getFmoney();

        log.info("#payOrder# 订单完成了 , fMoney:{}", fMoney);

        log.info("#payOrder# 支付回调到达 payOrder");

        //为空或者0 者不需要进行f分抵扣
        if (fMoney == null || fMoney.equals(0D)) {
            order.setPayStatus(PayStatusEnum.PAID.name());
            order.setOrderStatus(OrderStatusEnum.PAID.name());
        } else {
            order.setPayStatus(PayStatusEnum.PLATFORM_PAID.name());
            order.setOrderStatus(OrderStatusEnum.PLATFORM_PAID.name());
//            User user = userClient.getById(order.getBuyerId());
//            String openId = user.getOpenId();

            /**
             *  isDeductMoney是否扣款成功, sdk返回值
             */
            boolean isDeductMoney = true;
            //TODO 调用sdk扣除余额
            order.setOutTradeNo(paymentLog.getOutTradeNo());
//            log.info("obj -- 进来了");
            try {
                JSONObject obj = payApi.freePay(2, 5, "购买商品F分抵扣"
                        , new BigInteger(String.valueOf(CurrencyUtil.mul(order.getPriceDetailDTO().getFmoney(), 100).longValue())),
                        order.getSn(), order.getFreePayKey(), new BigInteger("0"));
                System.out.println(obj);
                isDeductMoney = true;
            } catch (Exception e) {
                e.printStackTrace();
                isDeductMoney = false;
            }
//            log.info("obj -- " + JSONObject.toJSONString(obj));

            if (isDeductMoney) {
                order.setPayStatus(PayStatusEnum.PAID.name());
                order.setOrderStatus(OrderStatusEnum.PAID.name());
            } else {
                //f分不足时，直接退款
                order.setOutTradeNo(paymentLog.getOutTradeNo());
                order.setTransactionId(paymentLog.getTransactionId());
                order.setCanReturn(PaymentMethodEnum.canReturnOnline(paymentLog.getPaymentMethod()));
                this.updateById(order);
                //return this.cancel(order.getSn(), "f分不足以进行抵扣", order.getBuyerId());
            }
        }

        order.setOutTradeNo(paymentLog.getOutTradeNo());
        order.setTransactionId(paymentLog.getTransactionId());
        order.setCanReturn(PaymentMethodEnum.canReturnOnline(paymentLog.getPaymentMethod()));
        boolean flag1 = this.updateById(order);


        // 执行异步保存日志方法 2024-02-21
        Objects.requireNonNull(threadConfig.getAsyncExecutor()).execute(() -> {
            //记录支付回调方法,执行日志OrerServiceImpl.payOrder.updateId
            PaymentCallbackOrderLog callbackOrderLog = new PaymentCallbackOrderLog();
            callbackOrderLog.setOutTradeOn(paymentLog.getOutTradeNo());
            callbackOrderLog.setOrderSn(paymentLog.getOrderSn());
            callbackOrderLog.setTransactionId(paymentLog.getTransactionId());
            callbackOrderLog.setMethodName("OrerServiceImpl.payOrder.updateId()");
            callbackOrderLog.setParams(JSONObject.toJSONString(order));
            callbackOrderLog.setExecResult("" + flag1);
            boolean flag = paymentCallbackOrderLogService.save(callbackOrderLog);
            if(flag){
                log.info("OrerServiceImpl.payOrder.updateId() --> paymentCallbackOrderLogService.save: {} ,", flag);
            }
        });


        //发送订单已付款消息
        OrderMessage orderMessage = new OrderMessage();
        orderMessage.setOrderSn(order.getSn());
        orderMessage.setPaymentMethod(order.getPaymentMethod());
        orderMessage.setNewStatus(OrderStatusEnum.PAID);
        this.sendUpdateStatusMessage(orderMessage);

        String message = "订单付款，付款方式[" + PaymentMethodEnum.valueOf(order.getPaymentMethod())
                .paymentName() + "]";


        List<OrderItem> orderItems = orderItemService.getByOrderSn(order.getSn());
        //24小时内是否存在点击分享的商品链接
        String existFlag = cache.getString(CommonConstant.TEMP_SHARE_GOODS_PARENT_KEY + order.getBuyerId());
        //是否已经被绑定过关系了
        String existRelationship = cache.getString(CommonConstant.EXIST_SHARE_GOODS_RELATIONSHIP + order.getBuyerId());
        if (StrUtil.isNotBlank(existFlag) && StrUtil.isBlank(existRelationship)) {
            this.execBindParents(orderItems, order.getBuyerId());
        }
        orderFlowService.payOrder(order, orderItems);
        log.info("1.orderItems====" + JSONObject.toJSONString(orderItems));

        OrderLog orderLog = new OrderLog(order.getSn(), "-1", SceneEnums.SYSTEM.name(), "系统操作", message);
        orderLogService.save(orderLog);
        log.info("orderLog====" + JSONObject.toJSONString(orderLog));

        log.info("orderItems====" + JSONObject.toJSONString(orderItems));

        Map<String,JSONObject> map = new HashMap<>();
        //下单后更新盲盒统计、发放礼包相关
        orderItems.forEach(orderItem -> {
            CallbackBlindboxDTO callbackBlindboxDTO = new CallbackBlindboxDTO();
            callbackBlindboxDTO.setUserId(paymentLog.getPayerId());
            callbackBlindboxDTO.setGoodsId(orderItem.getGoodsId());
            callbackBlindboxDTO.setGoodsName(orderItem.getGoodsName());
            callbackBlindboxDTO.setOrderId(order.getId());
            callbackBlindboxDTO.setOrderNumber(orderItem.getNum());
            callbackBlindboxDTO.setOrderSn(orderItem.getOrderSn());
            callbackBlindboxDTO.setOrderItemSn(orderItem.getSn());
            Boolean flag = blindboxCountClient.callbackBlindbox(callbackBlindboxDTO);
            /*if(!flag){
                throw new ServiceException(ResultCode.ORDER_NOT_EXIST_INVENTORY);
            }*/
//            boxMhGoodsClient.callbackMhGoods(callbackBlindboxDTO);
            //派发礼包相关
            if (StrUtil.isNotEmpty(orderItem.getPackId())) {
                if (map.containsKey(orderItem.getPackId())) {
                    JSONObject mapJSONO = map.get(orderItem.getPackId());
                    mapJSONO.put("num", mapJSONO.getInteger("num") + orderItem.getNum());
                    map.put(orderItem.getPackId(), mapJSONO);
                } else {
                    JSONObject json = new JSONObject();
                    json.put("goodName", orderItem.getGoodsName());
                    json.put("num", orderItem.getNum());
                    map.put(orderItem.getPackId(), json);
                }
            }
        });
        //派发礼包相关
        if (CollUtil.isNotEmpty(map)) {
            User user = userClient.getById(order.getBuyerId());
            log.info("#payOrder# 派发礼包相关");
            //发放PLUS会员或者设置弹窗信息
            this.givePackGiftToUser(map, user, order.getSn());
        }
        //异步执行 第三方接口下单
        Objects.requireNonNull(threadConfig.getAsyncExecutor()).execute(()->{
            log.info("异步执行 第三方接口下单");
            //调用壹邦玖供应链，下单并扣款。
            this.payAppOrder(order);
            //第三方-采集下单（企叮当）
            GrabOrderParam grabOrderParam = new GrabOrderParam();
            grabOrderParam.setOrder(order);
            grabOrderParam.setOrderItems(orderItems);
            grabOrderClient.grabOrder(grabOrderParam);

            //异步生成用户全返卷
            orderItems.forEach(item-> returnActivityClient.generate(order.getBuyerId(),item));
        });
        //支付成功后发送请求门票分享请求
        Objects.requireNonNull(threadConfig.getAsyncExecutor()).execute(()->{
            log.info("支付成功后发送请求门票分享请求-----");
            User user = userClient.getById(order.getBuyerId());
            log.info("调用飞语接口请求-----{}",user.getOpenId());
            OpenAppUser openAppUser = userApi.getOtherUserInfoByOpenId("fy_ds7d8s9ad7",user.getOpenId());
            log.info("调用飞语接口请求结束-----{}",JSONObject.toJSONString(openAppUser));
            HttpRequest request = HttpUtil.createGet("http://share.chainlettre06.com/api/Member/notice?openid="+openAppUser.getOpenId());
            JSONObject jsonObject = JSONObject.parseObject(request.execute().body());
            log.info("调用客帮请求结束-----{}",JSONObject.toJSONString(jsonObject));
        });

        //支付成功后进行判断当前用户是否有上级，并且上级是分销员。有则添加积分变动记录，与变动佣金
        Objects.requireNonNull(threadConfig.getAsyncExecutor()).execute(()->{
            log.info("进行判断当前用户是否有上级，并且上级是分销员-----");
            User user = userClient.getById(order.getBuyerId());
            String parentOpenId = userApi.getParent(user.getOpenId());
            if (StringUtils.isEmpty(parentOpenId)) {
                return;
            }
            User memberUser = userClient.getByOpenId(parentOpenId, SceneEnums.MEMBER.name());
            if (memberUser == null || StringUtils.isEmpty(memberUser.getId())) {
                return;
            }
//            Distribution distribution = distributionClient.getDistribution(memberUser.getId());
            RankingDistribution distribution = rankingDistributionService.getRankingDistributionByMemberId(memberUser.getId());
            if (distribution == null || StringUtils.isEmpty(distribution.getId()) || !DistributionStatusEnum.PASS.name().equals(distribution.getDistributionStatus())) {
                return;
            }
            //上级是分销员 ==》 生成积分记录并给上级分销员增加积分总额
            for (OrderItem orderItem : orderItems) {
                GoodsSku goodsSku = goodsSkuClient.getGoodsSkuById(orderItem.getSkuId());
                //积分业绩
                if(!(goodsSku.getGreenScore() != null && goodsSku.getGreenScore() > 0)) {
                    return;
                }
                JSONObject jsonObject = JSONObject.parseObject(settingClient.get(SettingEnum.GREEN_GOODS.name()).getSettingValue());
                Integer distributionProportion = jsonObject.getInteger("distributionProportion");
                double score = CurrencyUtil.mul(CurrencyUtil.div(CurrencyUtil.mul(goodsSku.getGreenScore(), distributionProportion == null ? 0 : distributionProportion), 100), orderItem.getNum());

                //获取当前排名活动
                RankingActivityConfig rankingActivityConfig = activityConfigService.getCurrentActivity();
                //构建积分记录并保存
                RankingScoreDetails rankingScoreDetails = RankingScoreDetails.builder()
                        .parentUserId(memberUser.getId())
                        .parentNickName(memberUser.getNickName())
                        .buyerUserId(user.getId())
                        .currentActivityId(rankingActivityConfig != null ? rankingActivityConfig.getId() : null)
                        .productId(orderItem.getSkuId())
                        .productName(orderItem.getGoodsName())
                        .score(BigDecimal.valueOf(score))
                        .orderSn(orderItem.getSn())
                        .orderStatus(DictConstant.SCORE_ORDER_STATUS_01)
                        .build();
                scoreDetailsService.save(rankingScoreDetails);

                // 添加积分总额
//                distributionClient.addGrossCommission(distribution.getId(), BigDecimal.valueOf(score));
                rankingDistributionService.addGrossCommission(distribution.getId(), BigDecimal.valueOf(score));
            }
            // 添加直推数量
//            distributionClient.addDirectOrderNumber(distribution.getId());
            RankingDistribution param = new RankingDistribution();
            param.setId(distribution.getId());
            param.setDirectOrderNumber(1);
            rankingDistributionService.updateRankingDistribution(param);
        });

        //检测是否存在更新分享注册里的首次购买标识
        Objects.requireNonNull(threadConfig.getAsyncExecutor()).execute(()->{

            User user = userClient.getById(order.getBuyerId());
            log.info("#payOrder# 检测是否存在更新分享注册里的首次购买标识,查到的 user:{}", JSONObject.toJSONString(user));
            if (user != null) {
                firstBuyRecordService.judeUpdateFirstBuyRecord(user.getId(), user.getOpenId(), user.getMobile());
            }

        });
        //异步发放礼包相关
/*        Objects.requireNonNull(threadConfig.getAsyncExecutor()).execute(() -> {
            Map<String,JSONObject> map = new HashMap<>();
            for (OrderItem orderItem : orderItems) {
                if (StrUtil.isNotEmpty(orderItem.getPackId())) {
                    if (map.containsKey(orderItem.getPackId())) {
                        JSONObject mapJSONO = map.get(orderItem.getPackId());
                        mapJSONO.put("num",mapJSONO.getInteger("num") + orderItem.getNum());
                        map.put(orderItem.getPackId(), mapJSONO);
                    } else {
                        JSONObject json = new JSONObject();
                        json.put("goodName", orderItem.getGoodsName());
                        json.put("num", orderItem.getNum());
                        map.put(orderItem.getPackId(), json);
                    }
                }
            }
            if (CollUtil.isNotEmpty(map)) {
                User user = userClient.getById(order.getBuyerId());
                ///发放PLUS会员
                this.givePackGiftToUser(map, user, order.getSn());
            }
        });*/

        log.info("#OrerServiceImpl# #payOrder# 方法执行完毕,order_sn:{},tradeSn:{}", order.getSn(), order.getTradeSn());
        if (order.getIsDutyFree() != null && order.getIsDutyFree() && StrUtil.isNotEmpty(order.getBuyerCardNo())) {
            Objects.requireNonNull(threadConfig.getAsyncExecutor()).execute(() -> {
                log.info("#OrerServiceImpl# #payOrder# 异步记录用户年度免税交易量,order_sn:{},buyerCardNo:{},flowPrice:{}", order.getSn(), order.getBuyerCardNo(), order.getFlowPrice());
                //统计年度总交易量
                UserFreetaxOrderYearTotal userFree = new UserFreetaxOrderYearTotal();
                userFree.setBuyerCardNo(order.getBuyerCardNo());
                userFree.setYearDate(LocalDate.now().getYear());
                userFree.setTotalAmountYear(order.getFlowPrice());
                userFree.setUserId(order.getBuyerId());
                userFreetaxOrderYearTotalService.updateOrSaveUserFree(userFree);
            });
        }

        return order;
    }


    //发放PLUS会员
    public void givePackGiftToUser(Map<String,JSONObject> map, User user, String orderSn) {
        String plusVipKey = "plusVipMapKey";
        Map<String,Integer> plusVipMonthMap = new HashMap<>(1);
        plusVipMonthMap.put(plusVipKey, 0);
        List<String> goodNameList = new ArrayList<>();
        map.forEach((k, v) -> {
            PackConfigVO packConfigVo = packConfigClient.getById(k);
            if (packConfigVo == null || packConfigVo.getPackStatus() != 1) {
                log.info("#givePackGiftToUser# 派发礼包, 礼包不存在或者礼包不可用,退出派发,礼包id:{}", k);
                return;
            }
            if (StrUtil.isNotEmpty(packConfigVo.getDictVal()) && !packConfigVo.getDictVal().equals("0")) {
                plusVipMonthMap.put(plusVipKey, plusVipMonthMap.get(plusVipKey) + Integer.valueOf(packConfigVo.getDictVal()) * v.getInteger("num"));
                goodNameList.add(v.getString("goodName"));
            }else{
                Distribution distribution = distributionClient.getDistribution(user.getId());
                log.info("#givePackGiftToUser# 派发礼包 ,查询是否店主, 参数: userId:{},结果:{}", user.getId(), distribution != null ? JSONObject.toJSONString(distribution) : null);
                if (distribution != null && distribution.getDistributionStatus().equals(DistributionStatusEnum.PASS.name())) {
                    log.info("#givePackGiftToUser# 派发礼包 ,店主礼包派发, 参数: userId:{},已经是店主,正常退出派发", user.getId());
                    return;
                }
                //店主礼包
                OrderPackVO plusVO = new OrderPackVO();
                plusVO.setGoodName(v.getString("goodName"));
                plusVO.setIsDistribution(true);
                cache.put("store" + orderSn, JSONObject.toJSONString(plusVO), 30L, TimeUnit.MINUTES);
            }
        });
        //无plus VIP 派发
        if (plusVipMonthMap.get(plusVipKey) <= 0) {
            return;
        }

        LiVip liVip = vipClient.getByUserId(user.getId());
//        boolean isVip = liVip != null && liVip.getEndTimeTow() != null && liVip.getEndTimeTow().getTime() > new Date().getTime();
        boolean isVip = liVip != null && liVip.getEndTime() != null && liVip.getEndTime().getTime() > new Date().getTime();
        //还是会员 =》 在原有基础上 加xxx月
        if (isVip) {
            Date endTime = liVip.getEndTime();
            log.info("#givePackGiftToUser# 派发礼包,原始结束时间：" + endTime);
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(endTime);
            //在原有基础上+ n 月
            calendar.add(Calendar.MONTH, plusVipMonthMap.get(plusVipKey));
            Date newEndTime = calendar.getTime();
            log.info("#givePackGiftToUser# 派发礼包, 增加月份后的结束时间：" + newEndTime);
            liVip.setEndTime(newEndTime);
            vipClient.update(liVip);
           //存储礼包弹窗内容
            OrderPackVO plusVO = new OrderPackVO();
            plusVO.setGoodName(goodNameList.get(0));
            plusVO.setStartDate(new Date());
            plusVO.setEndDate(newEndTime);
            cache.put("plus" + orderSn, JSONObject.toJSONString(plusVO), 30L, TimeUnit.MINUTES);
            log.info("#givePackGiftToUser# 派发plus礼包,续期plus会员, 已送plus会员,并已存redis缓存,params:{},value:{}", "plus" + orderSn, JSONObject.toJSONString(plusVO));
            return;
        }
        //已经会员过期。  没有创建会员（去创建会员）
        else {
            //没有创建会员，去创建会员
            //创建到期时间
            LocalDateTime currentDateTime = LocalDateTime.now();
            LocalDateTime nextMonthSameDayTime = currentDateTime.plusMonths(plusVipMonthMap.get(plusVipKey));
            Date expireDate = Date.from(nextMonthSameDayTime.atZone(ZoneId.systemDefault()).toInstant());
            if (liVip == null) {
                // 创建VIP会员记录
                LiVip vip = LiVip.builder()
                        .userId(user.getId())
                        .vipStatus(VipStatusEnum.NORMAL.getStatus())
                        .openingMode(PayWayEnum.MANAGE_ADD.getValue())
                        .userName(user.getUsername())
                        .endTime(expireDate)
                        .phone(user.getMobile())
                        .build();
                vip.setCreateBy(user.getId());
                vip.setCreateTime(new Date());
                boolean save = vipClient.save(vip);
                //存储礼包弹窗内容
                OrderPackVO plusVO = new OrderPackVO();
                plusVO.setGoodName(goodNameList.get(0));
                plusVO.setStartDate(new Date());
                plusVO.setEndDate(vip.getEndTime());
                cache.put("plus" + orderSn, JSONObject.toJSONString(plusVO), 30L, TimeUnit.MINUTES);

                log.info("#givePackGiftToUser# 派发礼包, 创建plus会员, 已送plus会员,并已存redis缓存,params:{},value:{}", "plus" + orderSn, JSONObject.toJSONString(plusVO));
                return;
            }
            // 更新会员记录
            liVip.setEndTime(expireDate);
            vipClient.update(liVip);
            log.info("#givePackGiftToUser# 派发礼包 end 充值商城会员3");
            return;
        }
    }


    /**
     * 分享商品链接购买成功绑定上下级关系
     * @param
     */
    public void execBindParents(List<OrderItem> orderItems, String userId) {
        List<String> goodsIds = orderItems.stream().map(OrderItem::getGoodsId).distinct().collect(Collectors.toList());
        String strObj = "";
        for (String goodId : goodsIds) {
            strObj = cache.getString(CommonConstant.TEMP_SHARE_GOODS_PARENT_KEY + userId + goodId);
            if (StrUtil.isEmpty(strObj)) {
                continue;
            } else {
                break;
            }
        }
        if (StrUtil.isEmpty(strObj)) {
            return;
        }
        JSONObject jsonObject = JSONObject.parseObject(strObj);
        User user = new User();
        user.setId(jsonObject.getString("userId"));
        user.setParentId(jsonObject.getString("parentId"));
        user.setParentUsername(jsonObject.getString("parentUserName"));
        //分享绑定上下级增加绑定时间
        user.setParentBindTime(new Date());
        if(userClient.updateById(user)){
            Distribution dis = new Distribution();
            dis.setMemberId(user.getId());
            dis.setParentId(user.getParentId());
            dis.setParentUsername(user.getParentUsername());
            log.info("dis == {}", com.alibaba.fastjson.JSONObject.toJSONString(dis));
            try{
                distributionClient.updateDistributionParentInfo(dis);
            }catch (Exception e){
                log.info("#execBindParents# distributionClient.updateDistributionParentInfo() 失败,不影响正常绑定,无须回滚");
            }

            log.info("#execBindParents# userClient上下级关系保存成功,48小时存redis key:{}", CommonConstant.EXIST_SHARE_GOODS_RELATIONSHIP + userId);
            cache.put(CommonConstant.EXIST_SHARE_GOODS_RELATIONSHIP + userId, 1, 48L, TimeUnit.HOURS);
            cache.put(CommonConstant.TEMP_SHARE_GOODS_PARENT_KEY + user.getId() + jsonObject.get("goodsId"), jsonObject.toString(), 30L, TimeUnit.DAYS);
            cache.put(CommonConstant.TEMP_SHARE_GOODS_PARENT_KEY + user.getId(), CommonConstant.TEMP_SHARE_GOODS_PARENT_KEY + user.getId() + jsonObject.get("goodsId"), 30L, TimeUnit.DAYS);
        }else{
            log.info("#execBindParents# userClient上下级关系保存失败,绑定参数:{}", jsonObject.toJSONString());
        }
    }


    @Override
    @Transactional
    public void payOrderZero(String sn) {

        //订单列表
        List<Order> orders = this.getByTradeSn(sn);

        for (Order order : orders) {
            //修改订单状态
            order.setPaymentTime(new Date());
            order.setPaymentMethod(PaymentMethodEnum.BANK_TRANSFER.name());
            order.setPayStatus(PayStatusEnum.PAID.name());
            order.setOrderStatus(OrderStatusEnum.PAID.name());
            order.setOutTradeNo("-1");
            order.setTransactionId("-1");
            order.setCanReturn(false);
            this.updateById(order);

            //发送订单已付款消息
            OrderMessage orderMessage = new OrderMessage();
            orderMessage.setOrderSn(order.getSn());
            orderMessage.setPaymentMethod(order.getPaymentMethod());
            orderMessage.setNewStatus(OrderStatusEnum.PAID);
            this.sendUpdateStatusMessage(orderMessage);

            String message = "订单金额为0元，自动修改订单状态";


            orderFlowService.payOrder(order, orderItemService.getByOrderSn(order.getSn()));

            OrderLog orderLog = new OrderLog(order.getSn(), "-1", SceneEnums.SYSTEM.name(), "系统操作", message);
            orderLogService.save(orderLog);
        }
    }

    @Override
    public Page<OrderSimpleVO> queryByParams(OrderSearchParams orderSearchParams) {
        QueryWrapper queryWrapper = orderSearchParams.queryWrapper();
        queryWrapper.groupBy("o.id");
        queryWrapper.orderByDesc("o.id");
        this.addQueryWrapper(orderSearchParams, queryWrapper);
        Page<OrderSimpleVO> page = this.baseMapper.queryByParams(PageUtil.initPage(orderSearchParams), queryWrapper);
        if (!page.getRecords().isEmpty()) {
            page.getRecords().forEach(orderSimpleVO -> {
                if (StringUtils.isNotEmpty(orderSearchParams.getOrderPromotionType())
                        && orderSearchParams.getOrderPromotionType().equals(OrderPromotionTypeEnum.RED_PACK_GOODS.name())) {
                    PriceDetailDTO priceDetailDTO = PriceDetailDTO.getModel(orderSimpleVO.getPriceDetail());
                    orderSimpleVO.setFlowPrice(Double.valueOf(priceDetailDTO.getPayRedPack()));
                }
            });
        }

        //异步检查账户是否同步，没同步就去同步
        AuthUser currentUser = UserContext.getCurrentUser();
        Objects.requireNonNull(threadConfig.getAsyncExecutor()).execute(()->{
            this.checkAccount(currentUser);
        });
        return this.conversionQueryByParams(page);
    }

    /**
     * 检查账号是否同步，没有同步就去同步
     */
    private void checkAccount(AuthUser currentUser) {
        //log.info("checkAccount === ");
        log.info("currentUser === {}", JSONObject.toJSONString(currentUser));
        if (currentUser != null && StringUtils.isNotEmpty(currentUser.getUsername())) {
            FyUserInfo fyUserInfo = userApi.getFyUserInfo(currentUser.getUsername());
            log.info("fyUserInfo === {}", JSONObject.toJSONString(fyUserInfo));
            //查询不到此账号，说明账号已被修改。需同步数据
            if (fyUserInfo == null || StringUtils.isEmpty(fyUserInfo.getId())) {
                //获取新的账户信息
                OpenAppUser openAppUser = userApi.getUserinfoByOpenId(currentUser.getOpenId());
                log.info("openAppUser === {}", JSONObject.toJSONString(openAppUser));
                if (openAppUser != null && StringUtils.isNotEmpty(openAppUser.getAccount())) {
                    //同步账户信息
                    User user = new User();
                    user.setId(currentUser.getId());
                    user.setUsername(openAppUser.getAccount());
                    user.setAccount(openAppUser.getAccount());
                    user.setFyName(openAppUser.getNickName());
                    user.setFace(openAppUser.getAvater());
                    userClient.updateUserByIdAndMember(user);
                    log.info("success ===");
                }
            }
        }
    }

    /**
     * 字典转换
     */
    private Page<OrderSimpleVO> conversionQueryByParams(Page<OrderSimpleVO> page) {
        if (page == null || CollectionUtil.isEmpty(page.getRecords())) {
            return new Page<OrderSimpleVO>();
        }
        List<Dictionary> recycleList = dictionaryClient.getListByCode(DictConstant.RECYCLE_STATUS_NO);
        for (OrderSimpleVO simpleVO : page.getRecords()) {
            if (CollectionUtil.isNotEmpty(recycleList)) {
                for (Dictionary dictionary : recycleList) {
                    if (dictionary.getValue().equals(String.valueOf(simpleVO.getRecycleStatus()))) {
                        simpleVO.setRecycleStatusName(dictionary.getValueName());
                    }
                }
            }
        }
        return page;
    }

    @Override
    public Page<OrderSimpleVO> distributionQuery(DistributionOrderSearchParams distributionOrderSearchParams) {
        QueryWrapper queryWrapper = distributionOrderSearchParams.queryWrapper();
        queryWrapper.groupBy("o.id");
        queryWrapper.orderByDesc("o.id");
        return this.baseMapper.queryByParams(PageUtil.initPage(distributionOrderSearchParams), queryWrapper);
    }

    /**
     * 订单信息
     *
     * @param orderSearchParams 查询参数
     * @return 订单信息
     */
    @Override
    public List<Order> queryListByParams(OrderSearchParams orderSearchParams) {
        return this.baseMapper.queryListByParams(orderSearchParams.queryWrapper());
    }

    /**
     * 根据促销查询订单
     *
     * @param orderPromotionType 订单类型
     * @param payStatus          支付状态
     * @param parentOrderSn      依赖订单编号
     * @param orderSn            订单编号
     * @return 订单信息
     */
    @Override
    public List<Order> queryListByPromotion(String orderPromotionType, String payStatus, String parentOrderSn, String orderSn) {
        LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper<>();
        //查找团长订单和已和当前拼团订单拼团的订单
        queryWrapper.eq(Order::getOrderPromotionType, orderPromotionType)
                .eq(Order::getPayStatus, payStatus)
                .and(i -> i.eq(Order::getParentOrderSn, parentOrderSn)
                        .or(j -> j.eq(Order::getSn, orderSn)));
        return this.list(queryWrapper);
    }

    @Override
    public List<Order> queryListByPromotionId(String orderPromotionType, String payStatus, String parentOrderSn, String promotionId, String skuId) {
        //查找待拼团的订单
        return this.baseMapper.queryListByPromotionId(orderPromotionType, payStatus, parentOrderSn, promotionId, skuId);
    }

    /**
     * 根据促销查询订单
     *
     * @param orderPromotionType 订单类型
     * @param payStatus          支付状态
     * @param parentOrderSn      依赖订单编号
     * @param orderSn            订单编号
     * @return 订单信息
     */
    @Override
    public long queryCountByPromotion(String orderPromotionType, String payStatus, String parentOrderSn, String orderSn) {
        LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper<>();
        //查找团长订单和已和当前拼团订单拼团的订单
        queryWrapper.eq(Order::getOrderPromotionType, orderPromotionType).eq(Order::getPayStatus, payStatus).and(i -> i.eq(Order::getParentOrderSn,
                parentOrderSn).or(j -> j.eq(Order::getSn, orderSn)));
        return this.count(queryWrapper);
    }

    /**
     * 父级拼团订单
     *
     * @param pintuanId 拼团id
     * @return 拼团订单信息
     */
    @Override
    public List<Order> queryListByPromotion(String pintuanId) {
        LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Order::getOrderPromotionType, PromotionTypeEnum.PINTUAN.name());
        queryWrapper.eq(Order::getPromotionId, pintuanId);
        queryWrapper.nested(i -> i.eq(Order::getPayStatus, PayStatusEnum.PAID.name()).or(j -> j.eq(Order::getOrderStatus,
                OrderStatusEnum.PAID.name())));
        return this.list(queryWrapper);
    }

    /**
     * 添加盲盒店铺过滤条件 ==》 只查询当前盲盒店铺的订单
     * @param orderSearchParams
     * @param queryWrapper
     */
    public void addQueryWrapper(OrderSearchParams orderSearchParams, QueryWrapper queryWrapper) {
        AuthUser currentUser = UserContext.getCurrentUser();
        if (currentUser == null) {
            throw new ServiceException("登录已过期,请退出后重新登陆");
        }
        if (StrUtil.isNotEmpty(orderSearchParams.getPackId())) {
            queryWrapper.eq("oi.pack_id", orderSearchParams.getPackId());
        }

        if (orderSearchParams.getMhOrder() != null && orderSearchParams.getMhOrder() && !currentUser.getScene().equals(SceneEnums.MANAGER)) {
            List<Goods> goodsList = goodsClient.queryListByParams(GoodsSearchParams.builder().extendId(currentUser.getExtendId()).build());
            if (CollectionUtil.isEmpty(goodsList)) {
                queryWrapper.eq("o.id", -1);
            } else {
                List<BlindboxRuleOrder> ruleOrders = blindboxRelClient.getOrderByGoodsIds(goodsList.stream().map(Goods::getId).collect(Collectors.joining(",")));
                if (CollectionUtil.isEmpty(ruleOrders)) {
                    queryWrapper.eq("o.id", -1);
                } else {
                    queryWrapper.in("o.sn", ruleOrders.stream().map(BlindboxRuleOrder::getOrderSn).toList());
                }
            }
        }
        if (StringUtils.isNotEmpty(orderSearchParams.getOutTradeNo())) {
            queryWrapper.like("o.out_trade_no", orderSearchParams.getOutTradeNo());
        }
    }

    @Override
    public List<OrderExportDTO> queryExportOrder(OrderSearchParams orderSearchParams) {
        QueryWrapper queryWrapper = orderSearchParams.queryWrapper();
        this.addQueryWrapper(orderSearchParams, queryWrapper);
        List<OrderExportDTO> dataList = this.baseMapper.queryExportOrder(queryWrapper);

        //以下代码处理商品采集地址的回填
        if(null!=dataList && dataList.size()>0){
            List<Goods> goodsList = null;
            List<String> goodsIdList = dataList.stream().map(item->item.getGoodsId()).collect(Collectors.toSet()).stream().toList();
            GoodsSearchParams goodsSearchParams = new GoodsSearchParams();
            goodsSearchParams.setIds(goodsIdList);
            goodsList = goodsClient.queryListByParams(goodsSearchParams);
            if(null!=goodsList && goodsList.size()>0){
                List<Goods> finalGoodsList = goodsList;
                dataList.parallelStream().forEach(orderExportDTO -> {
                    if (CharSequenceUtil.isNotEmpty(orderExportDTO.getPriceDetail())) {
                        PriceDetailDTO priceDetailDTO = PriceDetailDTO.getModel(orderExportDTO.getPriceDetail());

                        if (StringUtils.isNotEmpty(orderSearchParams.getOrderPromotionType())
                                && orderSearchParams.getOrderPromotionType().equals(OrderPromotionTypeEnum.RED_PACK_GOODS.name())) {
                            orderExportDTO.setFlowPrice(Double.valueOf(priceDetailDTO.getPayRedPack()));
                        }

                        orderExportDTO.setSellerSettlementPrice(priceDetailDTO.getSellerSettlementPrice());
                        orderExportDTO.setSupplierSettlementPrice(priceDetailDTO.getSupplierSettlementPrice());
                        orderExportDTO.setPlatformSettlementPrice(priceDetailDTO.getPlatformSettlementPrice());
                        orderExportDTO.setGreenScore(priceDetailDTO.getGreenScore());
                        orderExportDTO.setSupplierGreenScore(priceDetailDTO.getSupplierGreenScore());

                        orderExportDTO.setSiteAddressGreenScore(priceDetailDTO.getSiteAddressGreenScore());
                        orderExportDTO.setSiteGreenScore(priceDetailDTO.getSiteGreenScore());
                        orderExportDTO.setUnionGreenScore(priceDetailDTO.getUnionGreenScore());
                        orderExportDTO.setCastellanGreenScore(priceDetailDTO.getCastellanGreenScore());
                        orderExportDTO.setLowerCommiss(priceDetailDTO.getLowerGreenScore());
                        orderExportDTO.setLowerSubCommiss(priceDetailDTO.getLowerSubGreenScore());
                        orderExportDTO.setStoreGreenScore(priceDetailDTO.getStoreGreenScore());
                        orderExportDTO.setMemberGreenScore(priceDetailDTO.getMemberGreenScore());
                        orderExportDTO.setGreenCommonwealGreenScore(priceDetailDTO.getGreenCommonwealGreenScore());

                        double platformGreenScore = CurrencyUtil.sub(priceDetailDTO.getGreenScore(),
                                priceDetailDTO.getMemberGreenScore(), priceDetailDTO.getStoreGreenScore(),
                                priceDetailDTO.getSupplierGreenScore(), priceDetailDTO.getSiteGreenScore(),
                                priceDetailDTO.getUnionGreenScore(), priceDetailDTO.getCastellanGreenScore(),
                                priceDetailDTO.getLowerGreenScore(), priceDetailDTO.getLowerSubGreenScore(),
                                priceDetailDTO.getGreenCommonwealGreenScore(),
                                priceDetailDTO.getSiteAddressGreenScore(), priceDetailDTO.getUnionGreenScore(), priceDetailDTO.getFmoney());
                        orderExportDTO.setPlatformGreenScore(platformGreenScore);
                        orderExportDTO.setFmoney(priceDetailDTO.getFmoney());
                        if (null == orderExportDTO.getCostPrice()) {
                            GoodsSku goodsSku = goodsSkuClient.getGoodsSkuByIdFromCache(orderExportDTO.getSkuId());
                            if (null != goodsSku) {
                                orderExportDTO.setCostPrice(goodsSku.getCost() != null ? goodsSku.getCost() : 0.0);
                            }
                        }
                    }
                    orderExportDTO.setConsigneeAddress(orderExportDTO.getConsigneeAddressPath() + orderExportDTO.getConsigneeDetail());

                    finalGoodsList.parallelStream().forEach(goods -> {
                        if(goods.getId().equals(orderExportDTO.getGoodsId())){
                            orderExportDTO.setGoodsGrabUrl(goods.getGoodsGrabUrl());
                            List<String> list = Arrays.asList(goods.getCategoryPath().split(","));
                            if (!list.isEmpty()) {
                                List<String> categoryList = (List<String>) categoryClient.getCategoryNameByIds(list);
                                if (!categoryList.isEmpty()) {
                                    String categoryPath = categoryList.stream().collect(Collectors.joining(","));
                                    orderExportDTO.setGoodsCategoryPath(categoryPath);
                                }
                            }
                        }
                    });
                });

            }
        }
        return dataList;
    }


    @Override
    public ResponseEntity<InputStreamResource> exportExcelByOrder (OrderSearchParams orderSearchParams) {
        try {
            String fileName = UserContext.getCurrentUser().getScene().name() + "_商品订单_" + System.currentTimeMillis() + ".xls";
            File xlsFile = new File("./" + fileName);
            WritableWorkbook workbook = jxl.Workbook.createWorkbook(xlsFile);
            WritableSheet sheet = workbook.createSheet("商品订单", 0);
            WritableFont wf = new WritableFont(WritableFont.TIMES,18,WritableFont.BOLD,true);
            WritableCellFormat wcf = new WritableCellFormat(wf);
            wcf.setBorder(jxl.format.Border.ALL,jxl.format.BorderLineStyle.THIN);
            List<String> titles = Lists.newArrayList();
            titles.add("订单编号");
            titles.add("交易流水号");
            titles.add("下单时间");
            titles.add("客户名称");
            titles.add("客户端类型");
            titles.add("支付方式");
            titles.add("订单金额");
            titles.add("订单成本");
            titles.add("商品编号");
            titles.add("商品名称");
            titles.add("商品分类");
            titles.add("商品数量");
            titles.add("商品价格");
            titles.add("商品成本价");
            titles.add("付款状态");
            titles.add("店铺");
            titles.add("商品采集地址");
            titles.add("订单状态");
            titles.add("收件人姓名");
            titles.add("收件人手机");
            titles.add("收货地址");
            titles.add("店铺结算金额");
            titles.add("供应商结算金额");
            titles.add("平台结算金额");
            titles.add("绿色积分");
            titles.add("用户绿色积分分佣");
            titles.add("店铺绿色积分分佣");
            titles.add("供应商绿色积分分佣");
            titles.add("城市站点绿色积分分佣");
            titles.add("城市地址绿色积分分佣");
            titles.add("平台绿色积分分佣");

            WritableCellFormat titleStyle = new WritableCellFormat(new WritableFont(WritableFont.createFont("微软雅黑"), 11, WritableFont.BOLD, false, UnderlineStyle.NO_UNDERLINE, Colour.BLACK));
            titleStyle.setBackground(Colour.SEA_GREEN);
            titleStyle.setAlignment(Alignment.CENTRE);
            titleStyle.setVerticalAlignment(jxl.format.VerticalAlignment.getAlignment(1));
            titleStyle.setBorder(Border.NONE, BorderLineStyle.NONE, Colour.BLACK);

            WritableCellFormat colmStyle = new WritableCellFormat(new WritableFont(WritableFont.createFont("微软雅黑"), 10, WritableFont.NO_BOLD, false, UnderlineStyle.NO_UNDERLINE, Colour.BLACK));
//        title.setBackground(Colour.VERY_LIGHT_YELLOW);
            colmStyle.setAlignment(Alignment.CENTRE);
            colmStyle.setVerticalAlignment(jxl.format.VerticalAlignment.getAlignment(1));
            colmStyle.setBorder(Border.NONE, BorderLineStyle.NONE, Colour.BLACK);

            for (int i = 0; i < titles.size(); i++) {
                Label label = new Label(i, 0, titles.get(i), titleStyle);
                sheet.addCell(label);
            }

            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss") ;
            List<OrderExportDTO> exportDataList = this.queryExportOrder(orderSearchParams);
            if (!exportDataList.isEmpty()) {
                int row = 1;
                Map<String, List<OrderExportDTO>> snMap = exportDataList.stream().collect(Collectors.groupingBy(OrderExportDTO::getSn));
                for (Map.Entry<String, List<OrderExportDTO>> entry : snMap.entrySet()) {
                    Double orderCost = entry.getValue().stream().mapToDouble(orderExport -> CurrencyUtil.mul(orderExport.getNum(), orderExport.getCostPrice())).sum();
                    for (OrderExportDTO orderExportDTO : entry.getValue()) {
                        int col = 0;
                        try {
                            sheet.addCell(new Label(col++, row, orderExportDTO.getSn(), colmStyle));
                            sheet.addCell(new Label(col++, row, orderExportDTO.getOutTradeNo(), colmStyle));
                            sheet.addCell(new Label(col++, row, sdf.format(orderExportDTO.getCreateTime()), colmStyle));
                            sheet.addCell(new Label(col++, row, orderExportDTO.getMemberName(), colmStyle));
                            sheet.addCell(new Label(col++, row, conversionClientTypeStr(orderExportDTO.getClientType()), colmStyle));
                            sheet.addCell(new Label(col++, row, StringUtils.isNotEmpty(orderExportDTO.getPaymentMethod()) ? conversionPaymentMethodStr(orderExportDTO.getPaymentMethod()) : "", colmStyle));
                            sheet.addCell(new Label(col++, row, orderExportDTO.getFlowPrice().toString(), colmStyle));
                            // 订单成本
                            sheet.addCell(new Label(col++, row, orderCost.toString(), colmStyle));

                            if (entry.getValue().size() > 1) {
                                sheet.mergeCells(0, row, 0, row + entry.getValue().size() - 1);
                                sheet.mergeCells(1, row, 1, row + entry.getValue().size() - 1);
                                sheet.mergeCells(2, row, 2, row + entry.getValue().size() - 1);
                                sheet.mergeCells(3, row, 3, row + entry.getValue().size() - 1);
                                sheet.mergeCells(4, row, 4, row + entry.getValue().size() - 1);
                                sheet.mergeCells(5, row, 5, row + entry.getValue().size() - 1);
                                sheet.mergeCells(6, row, 6, row + entry.getValue().size() - 1);
                            }

                            sheet.addCell(new Label(col++, row, orderExportDTO.getGoodsId(), colmStyle));
                            sheet.addCell(new Label(col++, row, orderExportDTO.getGoodsName(), colmStyle));
                            sheet.addCell(new Label(col++, row, orderExportDTO.getGoodsCategoryPath(), colmStyle));
                            sheet.addCell(new Label(col++, row, orderExportDTO.getNum().toString(), colmStyle));
                            sheet.addCell(new Label(col++, row, orderExportDTO.getGoodsPrice().toString(), colmStyle));
                            sheet.addCell(new Label(col++, row, orderExportDTO.getCostPrice().toString(), colmStyle));
                            sheet.addCell(new Label(col++, row, conversionPayStatusStr(orderExportDTO.getPayStatus()), colmStyle));
                            sheet.addCell(new Label(col++, row, orderExportDTO.getStoreName(), colmStyle));
                            sheet.addCell(new Label(col++, row, orderExportDTO.getGoodsGrabUrl(), colmStyle));
                            sheet.addCell(new Label(col++, row, conversionOrderStatusStr(orderExportDTO.getOrderStatus()), colmStyle));
                            sheet.addCell(new Label(col++, row, orderExportDTO.getConsigneeName(), colmStyle));
                            sheet.addCell(new Label(col++, row, orderExportDTO.getConsigneeMobile(), colmStyle));
                            sheet.addCell(new Label(col++, row, orderExportDTO.getConsigneeAddress(), colmStyle));
                            sheet.addCell(new Label(col++, row, orderExportDTO.getSellerSettlementPrice().toString(), colmStyle));
                            sheet.addCell(new Label(col++, row, orderExportDTO.getSupplierSettlementPrice().toString(), colmStyle));
                            sheet.addCell(new Label(col++, row, orderExportDTO.getPlatformSettlementPrice().toString(), colmStyle));
                            sheet.addCell(new Label(col++, row, orderExportDTO.getGreenScore().toString(), colmStyle));
                            sheet.addCell(new Label(col++, row, orderExportDTO.getMemberGreenScore().toString(), colmStyle));
                            sheet.addCell(new Label(col++, row, orderExportDTO.getStoreGreenScore().toString(), colmStyle));
                            sheet.addCell(new Label(col++, row, orderExportDTO.getSupplierGreenScore().toString(), colmStyle));
                            sheet.addCell(new Label(col++, row, orderExportDTO.getSiteGreenScore().toString(), colmStyle));
                            sheet.addCell(new Label(col++, row, orderExportDTO.getSiteAddressGreenScore().toString(), colmStyle));
                            sheet.addCell(new Label(col++, row, orderExportDTO.getPlatformGreenScore().toString(), colmStyle));
                        }catch (WriteException e) {
                            log.error("订单数据解析失败", e);
                            throw new ServiceException("订单数据解析失败");
                        }
                        row ++;
                    }
                }
            }
            workbook.write();
            workbook.close();

            FileSystemResource file = new FileSystemResource(xlsFile) ;
            HttpHeaders headers = new HttpHeaders();
            headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
            headers.add("Content-Disposition", "attachment; filename=" + URLEncoder.encode("商品订单", StandardCharsets.UTF_8) + ".xls");
            headers.add("Pragma", "no-cache");
            headers.add("Expires", "0");
            headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);

            return ResponseEntity
                    .ok()
                    .headers(headers)
                    .contentLength(file.contentLength())
                    .contentType(MediaType.APPLICATION_OCTET_STREAM)
                    .body(new InputStreamResource(file.getInputStream()));
        }catch (Exception e) {
            log.error("订单导出失败", e);
            throw new ServiceException("订单导出失败");
        }
    }

    private String conversionOrderStatusStr(String orderStatus) {
        switch (orderStatus) {
            case "UNPAID":
                return "未付款";
            case "PAID":
                return "已付款";
            case "PLATFORM_PAID":
                return "待F分抵扣";
            case "UNDELIVERED":
                return "待发货";
            case "DELIVERED":
                return "已发货";
            case "OVERVIEW":
                return "已揽件";
            case "COMPLETED":
                return "已完成";
            case "STAY_PICKED_UP":
                return "待自提";
            case "SUBJECT_TO_SALE":
                return "待售后";
            case "TAKE":
                return "待核验";
            case "CANCELLED_LODING":
                return "取消中";
            case "CANCELLED":
                return "已取消";
            default:
                return "未知";
        }
    }

    private String conversionPayStatusStr(String payStatus) {
        switch (payStatus) {
            case "UNPAID":
                return "待付款";
            case "PAID":
                return "已付款";
            case "CANCEL":
                return "已取消";
            case "PLATFORM_PAID":
                return "待F分抵扣";
            default:
                return "未知";
        }
    }

    public String conversionClientTypeStr (String clientType) {
        String clientTypeStr = "";
        switch (clientType) {
            case "H5":
                clientTypeStr = "移动端";
                break;
            case "PC":
                clientTypeStr = "PC端";
                break;
            case "WECHAT_MP":
                clientTypeStr = "小程序端";
                break;
            case "APP":
                clientTypeStr = "移动应用端";
                break;
            default:
                clientTypeStr = "未知";
                break;
        }
        return clientTypeStr;
    }

    public String conversionPaymentMethodStr (String paymentMethod) {
        String paymentMethodStr = "";
        switch (paymentMethod) {
            case "WECHAT":
                paymentMethodStr = "微信支付";
                break;
            case "ALIPAY":
                paymentMethodStr = "支付宝";
                break;
            case "WALLET":
                paymentMethodStr = "钱包支付";
                break;
            case "APPLE":
                paymentMethodStr = "苹果付款";
                break;
            case "BANK_TRANSFER":
                paymentMethodStr = "线下转账";
                break;
            default:
                paymentMethodStr = "未知";
        }
        return paymentMethodStr;
    }

    @Override
    public List<OrderExportDTO> queryExportOrderByWaitShip(OrderSearchParams orderSearchParams) {
        //List<OrderExportDTO> dataList = this.baseMapper.queryExportOrderByWaitShip(orderSearchParams.queryWrapper());
        List<OrderExportDTO> resultList = new ArrayList<>();
        QueryWrapper queryWrapper = orderSearchParams.queryWrapper();
        List<OrderExportDTO> dataList = this.baseMapper.queryExportOrderByWaitShip2(queryWrapper);
        if (!dataList.isEmpty()) {
            for (OrderExportDTO dto : dataList) {
                dto.setConsigneeAddress(dto.getConsigneeAddressPath() + dto.getConsigneeDetail());
                resultList.add(dto);
            }
            List<Goods> goodsList = null;
            List<String> goodsIdList = resultList.stream().map(item->item.getGoodsId()).collect(Collectors.toSet()).stream().toList();
            GoodsSearchParams goodsSearchParams = new GoodsSearchParams();
            goodsSearchParams.setIds(goodsIdList);
            goodsList = goodsClient.queryListByParams(goodsSearchParams);
            if(null!=goodsList && goodsList.size()>0) {
                for (OrderExportDTO orderExportDTO : resultList) {
                    if (orderExportDTO.getSendGoodsNum() != null && orderExportDTO.getSendGoodsNum() == 0) {
                        orderExportDTO.setSendGoodsNum(null);
                    }
                    for(Goods goods : goodsList){
                        if(goods.getId().equals(orderExportDTO.getGoodsId())){
                            orderExportDTO.setGoodsGrabUrl(goods.getGoodsGrabUrl());
                        }
                    }
                }
            }
        }
        return resultList;
    }

    @Override
    public OrderDetailVO queryDetail(String orderSn) {

        QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("sn", orderSn).or().eq("transaction_id",orderSn);
        Order tempOrder = this.getOne(queryWrapper);
        orderSn = tempOrder.getSn();

        AuthUser currentUser = UserContext.getCurrentUser();
        if (currentUser != null) {
            switch (currentUser.getScene()) {
                case MEMBER -> queryWrapper.eq("buyer_id", currentUser.getExtendId());
                case STORE -> queryWrapper.eq("store_id", currentUser.getExtendId()).or().eq("buyer_id",
                        currentUser.getExtendId());
                case SUPPLIER -> queryWrapper.eq("store_id", currentUser.getExtendId()).or().eq("supplier_id",
                        currentUser.getExtendId());
                case URBAN_SUBSTATION ->
                        queryWrapper.eq("urban_id_by_address", currentUser.getId()).or().eq("urban_id_by_supplier",
                                currentUser.getId());
                default -> {
                }
            }
        }


        Order order = this.getBySn(orderSn);
        if (order == null) {
            throw new ServiceException(ResultCode.ORDER_NOT_EXIST);
        }
        QueryWrapper<OrderItem> orderItemWrapper = new QueryWrapper<>();
        orderItemWrapper.eq(ORDER_SN_COLUMN, orderSn);
        //查询订单项信息
        List<OrderItem> orderItems = orderItemService.list(orderItemWrapper);
        //查询订单日志信息
        List<OrderLog> orderLogs = orderLogService.getOrderLog(orderSn);
        //赠品商品
        List<OrderItem> packItems = new ArrayList<>();
        //查询发票信息
        Receipt receipt = receiptService.getByOrderSn(orderSn);
        if (CollUtil.isNotEmpty(orderItems)) {
            List<OrderItem> removeOrderItems = new ArrayList<>();
            boolean isPackOrder = orderItems.stream().anyMatch(oItem -> StrUtil.isNotEmpty(oItem.getPackId()));
            order.setIsPackOrder(isPackOrder);
            if (isPackOrder) {
                for (OrderItem oItem : orderItems) {
                    //赠品商品
//                    if (oItem.getIsDeliver() == null || oItem.getIsDeliver()) {
                    OrderItem packOrderItem = new OrderItem();
                    BeanUtil.copyProperties(oItem, packOrderItem);
                    packOrderItem.setIsDeliver(oItem.getIsDeliver() != null && oItem.getIsDeliver());
                    packItems.add(packOrderItem);
                    //普通商品,或者需要发货的产品，不展示在上面商品栏
                    if (oItem.getPackId() == null || (oItem.getIsDeliver() != null && oItem.getIsDeliver())) {
                        removeOrderItems.add(oItem);
                    }
//                    }
                    //  是否是礼包商品
                    packOrderItem.setIsPackGift((oItem.getPackId() != null && oItem.getIsDeliver()!= null && !oItem.getIsDeliver()) ? true : false);
                    String packName = StrUtil.isNotEmpty(oItem.getPackName()) ? oItem.getPackName() : "";
                    oItem.setPackName(oItem.getGoodsName());
                    oItem.setGoodsName(packName);
                }
//                for (OrderItem oItem : orderItems) {
//                    if (StrUtil.isNotEmpty(oItem.getPackId())) {
//                        order.setIsPackOrder(true);
//                    }
//                    if (order.getIsPackOrder() != null && order.getIsPackOrder() && (oItem.getIsDeliver() == null || !oItem.getIsDeliver())) {
//                        //赠品商品
//                        OrderItem packOrderItem = new OrderItem();
//                        BeanUtil.copyProperties(oItem, packOrderItem);
//                        packItems.add(packOrderItem);
//                        String packName = StrUtil.isNotEmpty(oItem.getPackName()) ? oItem.getPackName() : "";
//                        oItem.setPackName(oItem.getGoodsName());
//                        oItem.setGoodsName(packName);
//                        //普通商品,或者需要发货的产品，不展示在上面商品栏
//                        if (oItem.getGoodsName().equals("")||oItem.getPackId() == null || (oItem.getIsDeliver() != null && oItem.getIsDeliver())) {
//                            removeOrderItems.add(oItem);
//                        }
//                    }
//                }
                orderItems.removeAll(removeOrderItems);
            }

        }
        // 查询座位号
        List<TicketOrder> ticketOrderList = ticketOrderClient.getListByTransactionSn(orderSn);
        //查询订单和自订单，然后写入vo返回
        return new OrderDetailVO(order, orderItems, orderLogs, receipt, ticketOrderList, packItems);
    }


    @Override
    @OrderLogPoint(description = "'订单['+#orderSn+']取消，原因为：'+#reason", orderSn = "#orderSn")
    @Transactional
    public Order cancel(String orderSn, String reason,String resultId, String... uid) {
        Order order = new Order();
        String openId = null;
        if (uid != null && uid.length > 0) {
            String str = "";
            for (String id : uid) {
                str = id;
            }
            User user = userClient.getById(str);
            AuthUser authUser = new AuthUser();
            BeanUtil.copyProperties(user, authUser);
            authUser.setScene(SceneEnums.getScene(user.getScene()));
            order = this.getBySnCancel(orderSn, authUser);
            openId = user.getOpenId();
            SceneHelp.objectAuthenticationCancel(order, authUser);
        } else {
            order = this.getBySn(orderSn);
            openId = UserContext.getCurrentUser() != null ? UserContext.getCurrentUser().getOpenId() : null;
            SceneHelp.objectAuthentication(order);
        }
//        Object orderSnVal = redisTemplate.boundValueOps("cancel-order::" + orderSn).get();
        //同一个订单，不是第一次请求，直接打回
//        if (orderSnVal != null && StringUtils.isNotEmpty((String) orderSnVal)) {
//            throw new ServiceException("重复请求");
//        }
//        redisTemplate.boundValueOps("cancel-order::" + orderSn).set(orderSn);
//        redisTemplate.expire("cancel-order::" + orderSn, 30, TimeUnit.MINUTES);

        //如果订单促销类型不为空&&订单是拼团订单，并且订单未成团，则抛出异常
        /*if (OrderPromotionTypeEnum.PINTUAN.name().equals(order.getOrderPromotionType()) && !order.getOrderStatus().equals(OrderStatusEnum.UNDELIVERED.name())) {
            throw new ServiceException(ResultCode.ORDER_CAN_NOT_CANCEL);
        }*/
        // 如果订单促销类型不为空&&订单是拼团订单，并且订单未成团，则抛出异常
        log.info("begin === ");
        if (CharSequenceUtil.equalsAny(order.getOrderStatus(), OrderStatusEnum.UNDELIVERED.name(), OrderStatusEnum.UNPAID.name(),
                OrderStatusEnum.PAID.name(), OrderStatusEnum.PLATFORM_PAID.name(), OrderStatusEnum.SUBJECT_TO_SALE.name(),OrderStatusEnum.CANCELLED_LODING.name())) {


            //存在供应链壹邦玖的商品，直接把状态修改为待售后。然后等待供应链回调退款。
            Boolean is = this.appOrderAfterSalesCreate(order, null);
            log.info("is == {}", is);
            if (is) {
                return order;
            }
            //企叮咚/胜创汇联取消订单
            if(orderManage.qqdCancelled(order,reason,resultId)){
                order.setOrderStatus(OrderStatusEnum.CANCELLED_LODING.name());
                order.setCancelReason(reason);
                this.updateById(order);
                return order;
            }
            //保税仓 取消订单（订单拦截）   &&  不是保税仓主动取消(直接去取消就行)  && 已经支付，订单已经生成
            if (order.getIsDutyFree() != null && order.getIsDutyFree() && !CommonConstant.CANCEL_REMARK.equals(reason)  && StringUtils.isNotEmpty(order.getOutTradeNo())) {
                List<OrderFreeStatusLog> orderFreeStatusLogList = orderFreeStatusLogService.list(new LambdaQueryWrapper<OrderFreeStatusLog>().eq(OrderFreeStatusLog::getOrderSn, order.getOutTradeNo()));
                //当有拦截记录，且只有状态为新订单时
                boolean isOrder = true;
                if (CollectionUtil.isNotEmpty(orderFreeStatusLogList)) {
                    for (OrderFreeStatusLog orderFreeStatusLog : orderFreeStatusLogList) {
                        if (CommonConstant.ORDER_STATUS_ORDER.equals(orderFreeStatusLog.getOrderStatus())) {
                            isOrder = false;
                            break;
                        }
                    }
                }
                //获取保税仓订单详情。如果订单不存在，或者订单状态已经是，已取消则不进行取消处理
                InterceptReq orderDetailReq = new InterceptReq();
                orderDetailReq.setOrderNo(order.getOutTradeNo());
                orderDetailReq.setApiUrl(FreeWarehouseConstant.ORDER_QUERY_ONE);
                JSONObject orderDetailRes = goodsClient.sendHttpRequest(orderDetailReq);
                //001700006是不存在订单 ==》 不需要去取消订单
                Boolean isCancel = true;
                if ("001700006".equals(orderDetailRes.getString("resultCode"))) {
                    isCancel = false;
                }
                //查询到订单，但是。订单已经取消 == 》 不需要去取消订单
                if ("1".equals(orderDetailRes.getString("resultCode"))) {
                    JSONObject resultData = orderDetailRes.getJSONObject("resultData");
                    String orderStatus = resultData.getString("orderStatus");
                    if (orderStatus.equals(CommonConstant.ORDER_STATUS_CANCEL)) {
                        isCancel = false;
                    }
                }
                if (isCancel) {
                    //刚下单的订单直接取消，其他时候取消，走拦截
                    if (isOrder) {
                        InterceptReq intercept = new InterceptReq();
                        intercept.setOrderNo(order.getOutTradeNo());
                        intercept.setApiUrl(FreeWarehouseConstant.ORDER_CANCEL);
                        JSONObject interceptJson = goodsClient.sendHttpRequest(intercept);
                        //1是正常code   &&  001700006是不存在订单
                        if (interceptJson != null && !"1".equals(interceptJson.getString("resultCode")) && !"001700006".equals(interceptJson.getString("resultCode"))) {
                            log.error("取消订单失败 == {}", interceptJson.toJSONString());
                            throw new ServiceException("取消订单失败");
                        }
                    } else {
                        InterceptReq intercept = new InterceptReq();
                        intercept.setOrderNo(order.getOutTradeNo());
                        intercept.setRemarks("取消订单");
                        intercept.setInterceptType("CANCEL");
                        intercept.setClientCode("IKATS");
                        intercept.setApiUrl(FreeWarehouseConstant.INTERCEPT);
                        JSONObject interceptJson = goodsClient.sendHttpRequest(intercept);
                        //1是正常code   &&  001700006是不存在订单
                        if (interceptJson != null && !"1".equals(interceptJson.getString("resultCode")) && !"001700006".equals(interceptJson.getString("resultCode"))) {
                            log.error("取消订单失败 == {}", interceptJson.toJSONString());
                            throw new ServiceException("取消订单失败");
                        }
                    }
                }
            }
            order.setOrderStatus(OrderStatusEnum.CANCELLED.name());
            order.setCancelReason(reason);
            //修改订单
            this.updateById(order);

            // 更新门票订单状态
            ticketOrderClient.updateOrderStatus(orderSn, TicketOrderStatusEnum.CANCELLED.name());

            //退款
            refundFlowService.generatorRefundFlow(order);
            // 删除用户全返卷
            returnActivityClient.deleteUserReturnActivityByOrderSn(order.getBuyerId(), order.getSn());
            //退f分抵扣
            //boolean orderReturn = payApi.orderReturn(2, 3, "积分退回", new BigInteger(String.valueOf((long) (order.getPriceDetailDTO().getFmoney() * 100))), order.getOutTradeNo(), openId, new BigInteger("0"));
//            if (!reason.equals("f分不足以进行抵扣")) {
//                boolean orderReturn = payApi.payment(openId,"积分退回", (int) (order.getPriceDetailDTO().getFmoney() * 100),2, 3);
//            }
            //取消贡献值
            greenClient.settleDirect(order.getSn(),null, GreenAmountInfoStatusEnum.CANCELLED.name());

            orderStatusMessage(order);

            //取消订单后进行判断当前用户是否有上级，并且上级是分销员。有则添加积分变动记录，与变动佣金
            Order finalOrder = order;
            Objects.requireNonNull(threadConfig.getAsyncExecutor()).execute(()->{
                log.info("进行判断当前用户是否有上级，并且上级是分销员-----");
                User user = userClient.getById(finalOrder.getBuyerId());
                String parentOpenId = userApi.getParent(user.getOpenId());
                if (StringUtils.isEmpty(parentOpenId)) {
                    return;
                }
                User memberUser = userClient.getByOpenId(parentOpenId, SceneEnums.MEMBER.name());
                if (memberUser == null || StringUtils.isEmpty(memberUser.getId())) {
                    return;
                }
//                Distribution distribution = distributionClient.getDistribution(memberUser.getId());
                RankingDistribution distribution = rankingDistributionService.getRankingDistributionByMemberId(memberUser.getId());
                if (distribution == null || StringUtils.isEmpty(distribution.getId()) || !DistributionStatusEnum.PASS.name().equals(distribution.getDistributionStatus())) {
                    return;
                }
                List<OrderItem> orderItems = orderItemService.list(new LambdaQueryWrapper<OrderItem>().eq(OrderItem::getOrderSn, orderSn));
                //上级是分销员 ==》 生成积分记录并给上级分销员增加积分总额
                for (OrderItem orderItem : orderItems) {
                    GoodsSku goodsSku = goodsSkuClient.getGoodsSkuById(orderItem.getSkuId());
                    //积分业绩
                    if(!(goodsSku.getGreenScore() != null && goodsSku.getGreenScore() > 0)) {
                        return;
                    }
                    JSONObject jsonObject = JSONObject.parseObject(settingClient.get(SettingEnum.GREEN_GOODS.name()).getSettingValue());
                    Integer distributionProportion = jsonObject.getInteger("distributionProportion");
                    double score = CurrencyUtil.mul(CurrencyUtil.div(CurrencyUtil.mul(goodsSku.getGreenScore(), distributionProportion == null ? 0 : distributionProportion), 100), orderItem.getNum());

                    LambdaUpdateWrapper<RankingScoreDetails> updateWrapper = new LambdaUpdateWrapper<>();
                    updateWrapper.eq(RankingScoreDetails::getParentUserId, memberUser.getId());
                    updateWrapper.eq(RankingScoreDetails::getBuyerUserId, user.getId());
                    updateWrapper.eq(RankingScoreDetails::getOrderSn, orderItem.getSn());
                    updateWrapper.set(RankingScoreDetails::getOrderStatus, DictConstant.SCORE_ORDER_STATUS_03);
                    scoreDetailsService.update(updateWrapper);

                    //减少积分总额
//                    distributionClient.subtractCommission(distribution.getId(), BigDecimal.valueOf(score));
                    RankingDistribution param = new RankingDistribution();
                    param.setId(distribution.getId());
                    param.setGrossCommission(new BigDecimal(score).negate());
                    rankingDistributionService.updateRankingDistribution(param);
                }
            });

            //需要取肖的plus会员礼包
            Objects.requireNonNull(threadConfig.getAsyncExecutor()).execute(() -> {
                User user = userClient.getById(finalOrder.getBuyerId());
                List<OrderItem> orderItems = orderItemService.list(new LambdaQueryWrapper<OrderItem>().eq(OrderItem::getOrderSn, orderSn));
                //需要取肖的plus会员月数
                Integer plusVIPMonth = 0;
                for (OrderItem orderItem : orderItems) {
                    //查询处理礼包订单
                    if (StrUtil.isNotEmpty(orderItem.getPackId())) {
                        PackConfigVO packConfigVo = packConfigClient.getById(orderItem.getPackId());
                        if (packConfigVo == null || packConfigVo.getPackStatus() != 1) {
                            log.info("#cancel# 取消派发礼包, 礼包不存在或者礼包不可用,退出派发,礼包id:{}", orderItem.getPackId());
                            continue;
                        }
                        if (StrUtil.isNotEmpty(packConfigVo.getDictVal()) && !packConfigVo.getDictVal().equals("0")) {
                            plusVIPMonth += Integer.valueOf(packConfigVo.getDictVal()) * orderItem.getNum();
                        }
                    }
                }
                log.info("#cancel# 取消礼包订单plus会员, 当前取消的订单里包含plus会员礼包的月份:{} ", plusVIPMonth);
                //取消plus会员
                if (plusVIPMonth > 0) {
                    LiVip liVip = vipClient.getByUserId(user.getId());
                    log.info("#cancel# 取消礼包订单plus会员,  查询当前用户的会员情况,结果:{}", JSONObject.toJSONString(liVip));
                    if (liVip != null && liVip.getEndTime() != null) {
                        Date newEndTime = null;
                        //相差月份
//                        int monthNum = ToolsUtil.monthsBetween(new Date(), liVip.getEndTime());
//                        //计算出当前日期-monthNum的天数
//                        LocalDate currentDate = LocalDate.now();
//                        // 减去指定的月数
//                        LocalDate resultDate = currentDate.minusMonths(monthNum);
//                        // 计算当前日期减去几个月后的日期
//                        long oldDaysBetween = ChronoUnit.DAYS.between(resultDate, currentDate);
                        //计算需要减掉的天数: VIP的结束时间-需要减去的月份
                        Date newEndDateJuge = ToolsUtil.subtractMonths(liVip.getEndTime(), plusVIPMonth);
                        log.info("#cancel# 取消礼包订单plus会员,  理论减去月份后的结束日期:{}", newEndDateJuge);
                        if (newEndDateJuge.getTime() <= new Date().getTime()) {
                            //马上过期,改成昨天的时间
                            newEndTime = ToolsUtil.subtractDays(new Date(), 1);
                            //改成过期状态
                            liVip.setVipStatus(VipStatusEnum.EXPIRED.getStatus());
                        }else{
                            //减去月份
                            newEndTime = ToolsUtil.subtractMonths(liVip.getEndTime(), plusVIPMonth);
                        }
                        log.info("#cancel# 取消礼包订单plus会员,  最后减去月份后的结束日期:{}", newEndTime);
                        liVip.setEndTime(newEndTime);
                        vipClient.update(liVip);

//                        if (monthNum > 0) {
//                            if (plusVIPMonth > monthNum || plusVIPMonth == monthNum) {
//                                //马上过期,把日期改成昨天
//                                newEndTime = ToolsUtil.subtractDays(liVip.getEndTime(), 1);
//                            } else {
//                                //减掉 过期相差月份
//                                newEndTime = ToolsUtil.subtractMonths(liVip.getEndTime(), monthNum - plusVIPMonth);
//                            }
//                            liVip.setEndTime(newEndTime);
//                            vipClient.update(liVip);
//                        }

                    }

                }
            });

            return order;
        } else {
            throw new ServiceException(ResultCode.ORDER_CAN_NOT_CANCEL);
        }
    }
    @Override
    public Order cancelResult(String orderSn,String id) {
        Order order = this.getBySn(orderSn);
        order.setOrderStatus(OrderStatusEnum.UNDELIVERED.name());
        this.updateById(order);

        orderManage.updateOrderCancelRefuse(id);
        return order;
    }


    @Override
    public Boolean appOrderAfterSalesCreate(Order order, AfterSale afterSale) {
        boolean isSupply = false;
        List<OrderItem> orderItemList = new ArrayList<>();
        //未发货取消订单进来的售后，走全订单取消。   申请售后的只取消子订单
        log.info("afterSale == {}", JSONObject.toJSONString(afterSale));
        if (afterSale != null) {
            OrderItem orderItem = orderItemService.getBySn(afterSale.getOrderItemSn());
            log.info("orderItem = ={}", JSONObject.toJSONString(orderItem));
            if (orderItem != null) {
                orderItemList.add(orderItem);
            }
        } else {
            orderItemList = orderItemService.getByOrderSn(order.getSn());
            order.setSupplyChainState(1);
            order.setOrderStatus(OrderStatusEnum.SUBJECT_TO_SALE.name());
            log.info("order = ={}", JSONObject.toJSONString(order));
            super.updateById(order);
        }
        log.info("orderItemList == {}", JSONObject.toJSONString(orderItemList));
        Integer after_sales_id = null;
        for (OrderItem orderItem : orderItemList) {
            GoodsSku goodsSku = goodsSkuClient.getGoodsSkuById(orderItem.getSkuId());
            log.info("goodsSku == {}", JSONObject.toJSONString(goodsSku));
            log.info("orderItem == {}", JSONObject.toJSONString(orderItem));
            //供应链支付完成的信息不为空，则表示是供应链商品，  如果类型为1这代表是，壹邦玖供应链
            if (goodsSku != null && Integer.valueOf(1).equals(goodsSku.getThirdPartyPlatformType()) && StringUtils.isNotEmpty(orderItem.getOrderJsonVal())) {
                AppAfterSalesCreate appAfterSalesCreate = new AppAfterSalesCreate();
                appAfterSalesCreate.setOrder_item_id(Integer.valueOf(orderItem.getSupplyChainOrderId()));
                appAfterSalesCreate.setThird_order_sn(orderItem.getSn());
                JSONObject jsonObject = this.appAfterSalesCreate(appAfterSalesCreate, order.getOrderStatus(), afterSale);
                after_sales_id = jsonObject.getInteger("data");
                log.info("after_sales_id == {}",  after_sales_id);
                orderItem.setAfterSalesId(after_sales_id);
                orderItemService.updateById(orderItem);
                isSupply = true;
            }
        }
//        if (isSupply) {
//            order.setSupplyChainState(1);
//            order.setOrderStatus(OrderStatusEnum.SUBJECT_TO_SALE.name());
//            super.updateById(order);
//        }
        return isSupply;
    }

    @Override
    @OrderLogPoint(description = "'订单['+#orderSn+']取消，原因为：'+#reason", orderSn = "#orderSn")
    @Transactional
    public Order cancel(String orderSn, String reason, String uid) {
        User user = userClient.getById(uid);
        AuthUser authUser = new AuthUser();
        BeanUtil.copyProperties(user, authUser);
        authUser.setScene(SceneEnums.getScene(user.getScene()));
        Order order = this.getBySnCancel(orderSn, authUser);
        String openId = user.getOpenId();
        SceneHelp.objectAuthenticationCancel(order, authUser);

        //如果订单促销类型不为空&&订单是拼团订单，并且订单未成团，则抛出异常
        /*if (OrderPromotionTypeEnum.PINTUAN.name().equals(order.getOrderPromotionType()) && !order.getOrderStatus().equals(OrderStatusEnum.UNDELIVERED.name())) {
            throw new ServiceException(ResultCode.ORDER_CAN_NOT_CANCEL);
        }*/
        // 如果订单促销类型不为空&&订单是拼团订单，并且订单未成团，则抛出异常
        if (CharSequenceUtil.equalsAny(order.getOrderStatus(), OrderStatusEnum.UNDELIVERED.name(), OrderStatusEnum.UNPAID.name(),
                OrderStatusEnum.PAID.name(), OrderStatusEnum.PLATFORM_PAID.name(), OrderStatusEnum.SUBJECT_TO_SALE.name())) {

            order.setOrderStatus(OrderStatusEnum.CANCELLED.name());
            order.setCancelReason(reason);
            //修改订单
            this.updateById(order);
            //退款
            refundFlowService.generatorRefundFlow(order);
            // 更新门票订单状态
            ticketOrderClient.updateOrderStatus(orderSn, TicketOrderStatusEnum.CANCELLED.name());

            // 删除用户全返卷
            returnActivityClient.deleteUserReturnActivityByOrderSn(order.getBuyerId(), order.getSn());

            //退f分抵扣
            //boolean orderReturn = payApi.orderReturn(2, 3, "积分退回", new BigInteger(String.valueOf((long) (order.getPriceDetailDTO().getFmoney() * 100))), order.getOutTradeNo(), openId, new BigInteger("0"));
//            if (!reason.equals("f分不足以进行抵扣")) {
//                boolean orderReturn = payApi.payment(openId,"积分退回", (int) (order.getPriceDetailDTO().getFmoney() * 100),2, 3);
//            }
            orderStatusMessage(order);

            //取消订单后进行判断当前用户是否有上级，并且上级是分销员。有则添加积分变动记录，与变动佣金
            Objects.requireNonNull(threadConfig.getAsyncExecutor()).execute(()->{
                log.info("进行判断当前用户是否有上级，并且上级是分销员-----");
                String parentOpenId = userApi.getParent(user.getOpenId());
                if (StringUtils.isEmpty(parentOpenId)) {
                    return;
                }
                User memberUser = userClient.getByOpenId(parentOpenId, SceneEnums.MEMBER.name());
                if (memberUser == null || StringUtils.isEmpty(memberUser.getId())) {
                    return;
                }
//                Distribution distribution = distributionClient.getDistribution(memberUser.getId());
                RankingDistribution distribution = rankingDistributionService.getRankingDistributionByMemberId(memberUser.getId());
                if (distribution == null || StringUtils.isEmpty(distribution.getId()) || !DistributionStatusEnum.PASS.name().equals(distribution.getDistributionStatus())) {
                    return;
                }
                List<OrderItem> orderItems = orderItemService.list(new LambdaQueryWrapper<OrderItem>().eq(OrderItem::getOrderSn, orderSn));
                //上级是分销员 ==》 生成积分记录并给上级分销员增加积分总额
                for (OrderItem orderItem : orderItems) {
                    GoodsSku goodsSku = goodsSkuClient.getGoodsSkuById(orderItem.getSkuId());
                    //积分业绩
                    if(!(goodsSku.getGreenScore() != null && goodsSku.getGreenScore() > 0)) {
                        return;
                    }
                    JSONObject jsonObject = JSONObject.parseObject(settingClient.get(SettingEnum.GREEN_GOODS.name()).getSettingValue());
                    Integer distributionProportion = jsonObject.getInteger("distributionProportion");
                    double score = CurrencyUtil.mul(CurrencyUtil.div(CurrencyUtil.mul(goodsSku.getGreenScore(), distributionProportion == null ? 0 : distributionProportion), 100), orderItem.getNum());

                    LambdaUpdateWrapper<RankingScoreDetails> updateWrapper = new LambdaUpdateWrapper<>();
                    updateWrapper.eq(RankingScoreDetails::getParentUserId, memberUser.getId());
                    updateWrapper.eq(RankingScoreDetails::getBuyerUserId, user.getId());
                    updateWrapper.eq(RankingScoreDetails::getOrderSn, orderItem.getSn());
                    updateWrapper.set(RankingScoreDetails::getOrderStatus, DictConstant.SCORE_ORDER_STATUS_03);
                    scoreDetailsService.update(updateWrapper);

                    //减少积分总额
//                    distributionClient.subtractCommission(distribution.getId(), BigDecimal.valueOf(score));
                    RankingDistribution param = new RankingDistribution();
                    param.setId(distribution.getId());
                    param.setGrossCommission(new BigDecimal(score).negate());
                    rankingDistributionService.updateRankingDistribution(param);
                }
            });
            return order;
        } else {
            throw new ServiceException(ResultCode.ORDER_CAN_NOT_CANCEL);
        }
    }

    private Order getBySnCancel(String orderSn, AuthUser authUser) {
        QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("sn", orderSn);
        if (authUser != null) {
            switch (Objects.requireNonNull(authUser).getScene()) {
                case MEMBER -> queryWrapper.eq("buyer_id", authUser.getExtendId());
                case SUPPLIER ->
                        queryWrapper.nested(n -> n.eq("supplier_id", authUser.getExtendId()).or().eq("store_id",
                                authUser.getExtendId()));
                case STORE -> queryWrapper.nested(n -> n.eq("store_id", authUser.getExtendId()).or().eq("buyer_id",
                        authUser.getExtendId()));
                default -> {
                }
            }
        }
        Order order = this.getOne(queryWrapper);
        if (order == null) {
            throw new ServiceException(ResultCode.ORDER_NOT_EXIST);
        }
        return order;
    }


    @Override
    @OrderLogPoint(description = "'订单['+#orderSn+']系统取消，原因为：'+#reason", orderSn = "#orderSn")
    @Transactional
    @ShardingTransactionType(TransactionType.BASE)
    public void systemCancel(String orderSn, String reason) {
        Order order = this.getBySn(orderSn);
        order.setOrderStatus(OrderStatusEnum.CANCELLED.name());
        order.setCancelReason(reason);
        this.updateById(order);
        //生成店铺退款流水
        refundFlowService.generatorRefundFlow(order);
        orderStatusMessage(order);

        //取消订单后进行判断当前用户是否有上级，并且上级是分销员。有则添加积分变动记录，与变动佣金
        Objects.requireNonNull(threadConfig.getAsyncExecutor()).execute(()->{
            log.info("进行判断当前用户是否有上级，并且上级是分销员-----");
            User user = userClient.getById(order.getBuyerId());
            String parentOpenId = userApi.getParent(user.getOpenId());
            if (StringUtils.isEmpty(parentOpenId)) {
                return;
            }
            User memberUser = userClient.getByOpenId(parentOpenId, SceneEnums.MEMBER.name());
            if (memberUser == null || StringUtils.isEmpty(memberUser.getId())) {
                return;
            }
//            Distribution distribution = distributionClient.getDistribution(memberUser.getId());
            RankingDistribution distribution = rankingDistributionService.getRankingDistributionByMemberId(memberUser.getId());
            if (distribution == null || StringUtils.isEmpty(distribution.getId()) || !DistributionStatusEnum.PASS.name().equals(distribution.getDistributionStatus())) {
                return;
            }
            List<OrderItem> orderItems = orderItemService.list(new LambdaQueryWrapper<OrderItem>().eq(OrderItem::getOrderSn, orderSn));
            //上级是分销员 ==》 生成积分记录并给上级分销员增加积分总额
            for (OrderItem orderItem : orderItems) {
                GoodsSku goodsSku = goodsSkuClient.getGoodsSkuById(orderItem.getSkuId());
                //积分业绩
                if(!(goodsSku.getGreenScore() != null && goodsSku.getGreenScore() > 0)) {
                    return;
                }
                JSONObject jsonObject = JSONObject.parseObject(settingClient.get(SettingEnum.GREEN_GOODS.name()).getSettingValue());
                Integer distributionProportion = jsonObject.getInteger("distributionProportion");
                double score = CurrencyUtil.mul(CurrencyUtil.div(CurrencyUtil.mul(goodsSku.getGreenScore(), distributionProportion == null ? 0 : distributionProportion), 100), orderItem.getNum());

                LambdaUpdateWrapper<RankingScoreDetails> updateWrapper = new LambdaUpdateWrapper<>();
                updateWrapper.eq(RankingScoreDetails::getParentUserId, memberUser.getId());
                updateWrapper.eq(RankingScoreDetails::getBuyerUserId, user.getId());
                updateWrapper.eq(RankingScoreDetails::getOrderSn, orderItem.getSn());
                updateWrapper.set(RankingScoreDetails::getOrderStatus, DictConstant.SCORE_ORDER_STATUS_03);
                scoreDetailsService.update(updateWrapper);

                //减少积分总额
//                distributionClient.subtractCommission(distribution.getId(), BigDecimal.valueOf(score));
                RankingDistribution param = new RankingDistribution();
                param.setId(distribution.getId());
                param.setGrossCommission(new BigDecimal(score).negate());
                rankingDistributionService.updateRankingDistribution(param);
            }
        });
    }

    /**
     * 获取订单
     *
     * @param orderSn 订单编号
     * @return 订单详情
     */
    @Override
    public Order getBySn(String orderSn) {

        QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("sn", orderSn).or().eq("transaction_id",orderSn);
        if (UserContext.getCurrentUser() != null) {
            switch (Objects.requireNonNull(UserContext.getCurrentUser()).getScene()) {
                case MEMBER -> queryWrapper.eq("buyer_id", UserContext.getCurrentUser().getExtendId());
                case SUPPLIER ->
                        queryWrapper.nested(n -> n.eq("supplier_id", UserContext.getCurrentUser().getExtendId()).or().eq("store_id",
                                UserContext.getCurrentUser().getExtendId()));
                case STORE ->
                        queryWrapper.nested(n -> n.eq("store_id", UserContext.getCurrentUser().getExtendId()).or().eq("buyer_id",
                                UserContext.getCurrentUser().getExtendId()));
                default -> {
                }
            }
        }

        Order order = this.getOne(queryWrapper);
        if (order == null) {
            throw new ServiceException(ResultCode.ORDER_NOT_EXIST);
        }
        return order;
    }

    @Override
    public Order checkDeliver(String orderSn) {
        Order order = this.getBySn(orderSn);
        //判断订单状促销状态不为空，且是否为赠品订单
        if (CharSequenceUtil.isNotEmpty(order.getOrderPromotionType()) && order.getOrderPromotionType().equals(OrderPromotionTypeEnum.GIFT.name())) {

            List<Order> orders = this.getByTradeSn(order.getTradeSn());
            orders.forEach(o -> {
                //判定当前店铺订单
                if (o.getStoreId().equals(order.getStoreId())) {
                    //判断订单状态是否为待发货&&订单促销类型不为空&&订单促销类型不为赠品
                    if (o.getDeliverStatus().equals(DeliverStatusEnum.UNDELIVERED.name()) &&
                            CharSequenceUtil.isNotEmpty(order.getOrderPromotionType()) &&
                            !o.getOrderPromotionType().equals(OrderPromotionTypeEnum.GIFT.name())) {
                        throw new ServiceException(ResultCode.ORDER_GIFT_DELIVER_ERROR);
                    }
                }
            });

        }
        return order;
    }

    @Override
    public Order getBySnNoAuth(String orderSn) {
        QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("sn", orderSn);
        Order order = this.getOne(queryWrapper);
        if (order == null) {
            throw new ServiceException(ResultCode.ORDER_NOT_EXIST);
        }
        return order;
    }

    @Override
    @OrderLogPoint(description = "'库存确认'", orderSn = "#orderSn")
    @Transactional
    @ShardingTransactionType(TransactionType.BASE)
    public void afterOrderConfirm(String orderSn) {
        Order order = this.getBySn(orderSn);
        //判断是否为拼团订单，进行特殊处理
        //判断订单类型进行不同的订单确认操作
        if (OrderPromotionTypeEnum.PINTUAN.name().equals(order.getOrderPromotionType())) {
            String parentOrderSn = CharSequenceUtil.isEmpty(order.getParentOrderSn()) ? orderSn : order.getParentOrderSn();
            this.checkPintuanOrder(order.getPromotionId(), parentOrderSn);
        } else {
            //判断订单类型
            if (order.getOrderType().equals(OrderTypeEnum.NORMAL.name()) || order.getOrderType().equals(OrderTypeEnum.PURCHASE.name())) {
                normalOrderConfirm(orderSn);
            } else {
                virtualOrderConfirm(orderSn);
            }
        }
    }


    @Override
    @SystemLogPoint(description = "修改订单", customerLog = "'订单[' + #orderSn + ']收货信息修改，修改为'+#memberAddressDTO.fullAddress+'")
    @Transactional
    @ShardingTransactionType(TransactionType.BASE)
    public Order updateConsignee(String orderSn, MemberAddressDTO memberAddressDTO) {
        Order order = this.getBySn(orderSn);

        //要记录之前的收货地址，所以需要以代码方式进行调用 不采用注解
        String message = "订单[" + orderSn + "]收货信息修改，由[" + order.getFullAddress() + "]修改为[" + memberAddressDTO.getFullAddress() + "]";
        //记录订单操作日志
        BeanUtil.copyProperties(memberAddressDTO, order);

        //修改物流信息
        this.updateAddress(order);
        this.updateById(order);

        OrderLog orderLog = new OrderLog(orderSn, UserContext.getCurrentUser().getId(), UserContext.getCurrentUser().getScene().value(),
                UserContext.getCurrentUser().getUsername(), message);
        orderLogService.save(orderLog);

        return order;
    }

    @Override
    @OrderLogPoint(description = "'订单['+#orderSn+']发货，发货单号['+#logisticsNo+']'", orderSn = "#orderSn")
    @Transactional
    @ShardingTransactionType(TransactionType.BASE)
    public Order delivery(String orderSn, String logisticsNo, String logisticsId) {
        Order order = this.checkDeliver(orderSn);

        //校验订单是否可以发货
        List<OrderFlow> orderFlowList = orderFlowService.list(new QueryWrapper<OrderFlow>().eq("order_sn", order.getSn()));
        if (orderFlowList != null) {
            orderFlowList.forEach(item -> {
                if (!item.verify()) {
                    throw new ServiceException(ResultCode.ORDER_VERIFY_ERROR, item.verifyMessage());
                }
            });
        }


        //如果订单未发货，并且订单状态值等于待发货
        if ((order.getDeliverStatus().equals(DeliverStatusEnum.UNDELIVERED.name()) && order.getOrderStatus().equals(OrderStatusEnum.UNDELIVERED.name()))||
                order.getDeliverStatus().equals(DeliverStatusEnum.OVERVIEW.name()) && order.getOrderStatus().equals(OrderStatusEnum.OVERVIEW.name())) {
            //获取对应物流
            Logistics logistics = logisticsClient.getById(logisticsId);
            if (logistics == null) {
                throw new ServiceException(ResultCode.ORDER_LOGISTICS_ERROR);
            }
            //写入物流信息
            order.setLogisticsCode(logistics.getId());
            order.setLogisticsName(logistics.getName());
            order.setLogisticsNo(logisticsNo);
            order.setLogisticsTime(new Date());
            order.setDeliverStatus(DeliverStatusEnum.DELIVERED.name());
            this.updateById(order);
            //修改订单状态为已发送
            this.updateStatus(orderSn, OrderStatusEnum.DELIVERED);
            //修改订单货物可以进行售后、投诉
            orderItemService.update(new UpdateWrapper<OrderItem>().eq(ORDER_SN_COLUMN, orderSn).set("after_sale_status",
                    OrderItemAfterSaleStatusEnum.NOT_APPLIED).set("complain_status", OrderComplaintStatusEnum.NO_APPLY));
            //发送订单状态改变消息
            OrderMessage orderMessage = new OrderMessage();
            orderMessage.setNewStatus(OrderStatusEnum.DELIVERED);
            orderMessage.setOrderSn(order.getSn());
            this.sendUpdateStatusMessage(orderMessage);
        } else {
            throw new ServiceException(ResultCode.ORDER_DELIVER_ERROR);
        }
        return order;
    }

    @Override
    @Transactional
    @ShardingTransactionType(TransactionType.BASE)
    public Boolean overview(String orderSns) {
        Arrays.stream(orderSns.split(",")).forEach(orderSn->{
            Order order = this.checkDeliver(orderSn);

            //校验订单是否可以览件
            List<OrderFlow> orderFlowList = orderFlowService.list(new QueryWrapper<OrderFlow>().eq("order_sn", order.getSn()));
            if (orderFlowList != null) {
                orderFlowList.forEach(item -> {
                    if (!item.verify()) {
                        throw new ServiceException(ResultCode.ORDER_VERIFY_ERROR, item.verifyMessage());
                    }
                });
            }


            //如果订单未发货，并且订单状态值等于待发货
            if (order.getDeliverStatus().equals(DeliverStatusEnum.UNDELIVERED.name()) && order.getOrderStatus().equals(OrderStatusEnum.UNDELIVERED.name())) {
                //写入物流信息
                order.setDeliverStatus(DeliverStatusEnum.OVERVIEW.name());
                this.updateById(order);
                //修改订单状态为已发送
                this.updateStatus(orderSn, OrderStatusEnum.OVERVIEW);
                //修改订单货物可以进行售后、投诉
                orderItemService.update(new UpdateWrapper<OrderItem>().eq(ORDER_SN_COLUMN, orderSn).set("after_sale_status",
                        OrderItemAfterSaleStatusEnum.NOT_APPLIED).set("complain_status", OrderComplaintStatusEnum.NO_APPLY));
                //发送订单状态改变消息
                OrderMessage orderMessage = new OrderMessage();
                orderMessage.setNewStatus(OrderStatusEnum.OVERVIEW);
                orderMessage.setOrderSn(order.getSn());
                this.sendUpdateStatusMessage(orderMessage);
            } else {
                throw new ServiceException(ResultCode.ORDER_OVERVIEW_ERROR);
            }
        });
        return Boolean.TRUE;
    }

    @Override
    public Boolean overviewOut(String orderSns) {
        Arrays.stream(orderSns.split(",")).forEach(orderSn->{
            Order order = this.checkDeliver(orderSn);

            //校验订单是否可以览件
            List<OrderFlow> orderFlowList = orderFlowService.list(new QueryWrapper<OrderFlow>().eq("order_sn", order.getSn()));
            if (orderFlowList != null) {
                orderFlowList.forEach(item -> {
                    if (!item.verify()) {
                        throw new ServiceException(ResultCode.ORDER_VERIFY_ERROR, item.verifyMessage());
                    }
                });
            }

            //如果订单未发货，并且订单状态值等于待发货
            if (order.getDeliverStatus().equals(DeliverStatusEnum.OVERVIEW.name())) {
                //写入物流信息
                order.setDeliverStatus(DeliverStatusEnum.UNDELIVERED.name());
                this.updateById(order);
                //修改订单状态为已发送
                this.updateStatus(orderSn, OrderStatusEnum.UNDELIVERED);
                //修改订单货物可以进行售后、投诉
                orderItemService.update(new UpdateWrapper<OrderItem>().eq(ORDER_SN_COLUMN, orderSn).set("after_sale_status",
                        OrderItemAfterSaleStatusEnum.NOT_APPLIED).set("complain_status", OrderComplaintStatusEnum.NO_APPLY));
                //发送订单状态改变消息
                OrderMessage orderMessage = new OrderMessage();
                orderMessage.setNewStatus(OrderStatusEnum.UNDELIVERED);
                orderMessage.setOrderSn(order.getSn());
                this.sendUpdateStatusMessage(orderMessage);
            } else {
                throw new ServiceException(ResultCode.ORDER_OVERVIEW_ERROR);
            }
        });
        return Boolean.TRUE;
    }

    @Override
    public Traces getTraces(String orderSn) {
        //获取订单信息
        Order order = this.getBySn(orderSn);
        //获取踪迹信息
        String str = order.getConsigneeMobile();
        return logisticsClient.getLogistic(order.getLogisticsCode(), order.getLogisticsNo(), str.substring(str.length() - 4));
    }

    @Override
    @OrderLogPoint(description = "'订单['+#orderSn+']核销，核销码['+#verificationCode+']'", orderSn = "#orderSn")
    @Transactional
    @ShardingTransactionType(TransactionType.BASE)
    public Order take(String orderSn, String verificationCode) {

        //获取订单信息
        Order order = this.getBySn(orderSn);
        //检测虚拟订单信息
        checkVerificationOrder(order, verificationCode);
        order.setOrderStatus(OrderStatusEnum.COMPLETED.name());
        //订单完成
        this.complete(orderSn);
        return order;
    }

    @Override
    public Order getOrderByVerificationCode(String verificationCode) {
        String storeId = Objects.requireNonNull(UserContext.getCurrentUser()).getExtendId();
        return this.getOne(new LambdaQueryWrapper<Order>().eq(Order::getOrderStatus, OrderStatusEnum.TAKE.name()).eq(Order::getStoreId, storeId).eq(Order::getVerificationCode, verificationCode));
    }

    @Override
    @OrderLogPoint(description = "'订单['+#orderSn+']完成'", orderSn = "#orderSn")
    @Transactional
    @ShardingTransactionType(TransactionType.BASE)
    public void complete(String orderSn) {
        //是否可以查询到订单
        Order order = this.getBySn(orderSn);
        complete(order, orderSn);
    }

    @Override
    @OrderLogPoint(description = "'订单['+#orderSn+']完成'", orderSn = "#orderSn")
    @Transactional
    @ShardingTransactionType(TransactionType.BASE)
    public void systemComplete(String orderSn) {
        Order order = this.getBySn(orderSn);
        complete(order, orderSn);
    }

    /**
     * 完成订单方法封装
     *
     * @param order   订单
     * @param orderSn 订单编号
     */
    @Transactional
    public void complete(Order order, String orderSn) {//修改订单状态为完成
        this.updateStatus(orderSn, OrderStatusEnum.COMPLETED);

        //修改订单货物可以进行评价
        orderItemService.update(new UpdateWrapper<OrderItem>().eq(ORDER_SN_COLUMN, orderSn).set("comment_status", CommentStatusEnum.UNFINISHED));
        this.update(new LambdaUpdateWrapper<Order>().eq(Order::getSn, orderSn).set(Order::getCompleteTime, new Date()));
        //发送订单状态改变消息
        OrderMessage orderMessage = new OrderMessage();
        orderMessage.setNewStatus(OrderStatusEnum.COMPLETED);
        orderMessage.setOrderSn(order.getSn());
        this.sendUpdateStatusMessage(orderMessage);

        //发送当前商品购买完成的信息（用于更新商品数据）
        List<OrderItem> orderItems = orderItemService.getByOrderSn(orderSn);
        List<GoodsCompleteMessage> goodsCompleteMessageList = new ArrayList<>();
        for (OrderItem orderItem : orderItems) {
            GoodsCompleteMessage goodsCompleteMessage = new GoodsCompleteMessage();
            goodsCompleteMessage.setGoodsId(orderItem.getGoodsId());
            goodsCompleteMessage.setSkuId(orderItem.getSkuId());
            goodsCompleteMessage.setBuyNum(orderItem.getNum());
            goodsCompleteMessage.setMemberId(order.getBuyerId());
            goodsCompleteMessageList.add(goodsCompleteMessage);

            if (StringUtils.isNotEmpty(orderItem.getOrderJsonVal())) {
                this.receive(orderItem);
            }
        }
        //发送商品购买消息
        if (!goodsCompleteMessageList.isEmpty()) {
            //发送订单变更mq消息
            amqpSender.send(AmqpMessage.builder().exchange(amqpExchangeProperties.getGoods()).routingKey(GoodsRoutingKey.BUY_GOODS_COMPLETE).message(goodsCompleteMessageList).build());
        }

        orderStatusMessage(order);
    }

    @Override
    public List<Order> getByTradeSn(String tradeSn) {
        LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper<>();
        return this.list(queryWrapper.eq(Order::getTradeSn, tradeSn));
    }

    @Override
    public List<Order> getByParentSn(String sn) {
        return list(new LambdaQueryWrapper<Order>().eq(Order::getParentOrderSn, sn));
    }

    @Override
    public void sendUpdateStatusMessage(OrderMessage orderMessage) {
        applicationEventPublisher.publishEvent(
                TransactionCommitSendMQEvent.builder()
                        .source("订单状态变更")
                        .exchange(amqpExchangeProperties.getOrder())
                        .routingKey(OrderRoutingKey.STATUS_CHANGE)
                        .message(orderMessage)
                        .build());
    }

    @Override
    @Transactional
    public void deleteOrder(String sn) {
        Order order = this.getBySn(sn);
        if (order == null) {
            log.error("订单号为" + sn + "的订单不存在！");
            throw new ServiceException();
        }
        LambdaUpdateWrapper<Order> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(Order::getSn, sn).set(Order::getDeleteFlag, true);
        this.update(updateWrapper);
        LambdaUpdateWrapper<OrderItem> orderItemLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        orderItemLambdaUpdateWrapper.eq(OrderItem::getOrderSn, sn).set(OrderItem::getDeleteFlag, true);
        this.orderItemService.update(orderItemLambdaUpdateWrapper);
    }

    @Override
    public Boolean invoice(String sn) {
        //根据订单号查询发票信息
        Receipt receipt = receiptService.getByOrderSn(sn);
        //校验发票信息是否存在
        if (receipt != null) {
            receipt.setReceiptStatus(1);
            return receiptService.updateById(receipt);
        }
        throw new ServiceException(ResultCode.USER_RECEIPT_NOT_EXIST);
    }

    /**
     * 自动成团订单处理
     *
     * @param pintuanId     拼团活动id
     * @param parentOrderSn 拼团订单sn
     */
    @Override
    @Transactional
    public void agglomeratePintuanOrder(String pintuanId, String parentOrderSn) {
        //获取拼团配置
        Pintuan pintuan = promotionsClient.getPintuanVO(pintuanId);
        List<Order> list = this.getPintuanOrder(pintuanId, parentOrderSn);
        if (Boolean.TRUE.equals(pintuan.getFictitious()) && pintuan.getRequiredNum() > list.size()) {
            //如果开启虚拟成团且当前订单数量不足成团数量，则认为拼团成功
            this.pintuanOrderSuccess(list);
        } else if (Boolean.FALSE.equals(pintuan.getFictitious()) && pintuan.getRequiredNum() > list.size()) {
            //如果未开启虚拟成团且当前订单数量不足成团数量，则认为拼团失败
            // 新需求可以一人成团，所以注释该代码
            //this.pintuanOrderFailed(list);
        }
    }

    @Override
    public void getBatchDeliverList(HttpServletResponse response, List<String> logisticsName) {
        ExcelWriter writer = ExcelUtil.getWriter();
        //Excel 头部
        ArrayList<String> rows = new ArrayList<>();
        rows.add("订单编号");
        rows.add("物流公司");
        rows.add("物流编号");
        writer.writeHeadRow(rows);

        //存放下拉列表  ----店铺已选择物流公司列表
        String[] logiList = logisticsName.toArray(new String[]{});
        CellRangeAddressList cellRangeAddressList = new CellRangeAddressList(1, 200, 1, 1);
        writer.addSelect(cellRangeAddressList, logiList);

        ServletOutputStream out = null;
        try {
            //设置公共属性，列表名称
            response.setContentType("application/vnd.ms-excel;charset=utf-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("批量发货导入模板", StandardCharsets.UTF_8) + ".xls");
            out = response.getOutputStream();
            writer.flush(out, true);
        } catch (Exception e) {
            log.error("获取待发货订单编号列表错误", e);
        } finally {
            writer.close();
            IoUtil.close(out);
        }

    }

    @Override
    @Transactional
    public void batchDeliver(MultipartFile files) {

        InputStream inputStream;
        List<OrderBatchDeliverDTO> orderBatchDeliverDTOList = new ArrayList<>();
        try {
            inputStream = files.getInputStream();
            //2.应用HUtool ExcelUtil获取ExcelReader指定输入流和sheet
            ExcelReader excelReader = ExcelUtil.getReader(inputStream);
            //可以加上表头验证
            //3.读取第二行到最后一行数据
            List<List<Object>> read = excelReader.read(1, excelReader.getRowCount());
            for (List<Object> objects : read) {
                OrderBatchDeliverDTO orderBatchDeliverDTO = new OrderBatchDeliverDTO();
                orderBatchDeliverDTO.setOrderSn(objects.get(0).toString());
                orderBatchDeliverDTO.setLogisticsName(objects.get(1).toString());
                orderBatchDeliverDTO.setLogisticsNo(objects.get(2).toString());
                orderBatchDeliverDTOList.add(orderBatchDeliverDTO);
            }
        } catch (Exception e) {
            throw new ServiceException(ResultCode.ORDER_BATCH_DELIVER_ERROR);
        }
        //循环检查是否符合规范
        checkBatchDeliver(orderBatchDeliverDTOList);
        //订单批量发货
        for (OrderBatchDeliverDTO orderBatchDeliverDTO : orderBatchDeliverDTOList) {
            this.delivery(orderBatchDeliverDTO.getOrderSn(), orderBatchDeliverDTO.getLogisticsNo(), orderBatchDeliverDTO.getLogisticsId());
        }
    }


    @Override
    public Page<PaymentLog> queryPaymentLogs(Page<PaymentLog> page, Wrapper<PaymentLog> queryWrapper) {
        return baseMapper.queryPaymentLogs(page, queryWrapper);
    }

    /**
     * 循环检查批量发货订单列表
     *
     * @param list 待发货订单列表
     */
    private void checkBatchDeliver(List<OrderBatchDeliverDTO> list) {

        List<Logistics> logistics = logisticsClient.list();
        for (OrderBatchDeliverDTO orderBatchDeliverDTO : list) {
            //查看订单号是否存在-是否是当前店铺的订单
            Order order =
                    this.getOne(new LambdaQueryWrapper<Order>().eq(Order::getStoreId, UserContext.getCurrentUser().getExtendId()).eq(Order::getSn,
                            orderBatchDeliverDTO.getOrderSn()));
            if (order == null) {
                throw new ServiceException("订单编号：'" + orderBatchDeliverDTO.getOrderSn() + " '不存在");
            } else if (!order.getOrderStatus().equals(OrderStatusEnum.UNDELIVERED.name())) {
                throw new ServiceException("订单编号：'" + orderBatchDeliverDTO.getOrderSn() + " '不能发货");
            }
            //获取物流公司
            logistics.forEach(item -> {
                if (item.getName().equals(orderBatchDeliverDTO.getLogisticsName())) {
                    orderBatchDeliverDTO.setLogisticsId(item.getId());
                }
            });
            if (CharSequenceUtil.isEmpty(orderBatchDeliverDTO.getLogisticsId())) {
                throw new ServiceException("物流公司：'" + orderBatchDeliverDTO.getLogisticsName() + " '不存在");
            }
        }


    }

    /**
     * 检查是否开始虚拟成团
     *
     * @param pintuanId   拼团活动id
     * @param requiredNum 成团人数
     * @param fictitious  是否开启成团
     * @return 是否成功
     */
    @Override
    @Transactional
    public boolean checkFictitiousOrder(String pintuanId, Integer requiredNum, Boolean fictitious) {
        Map<String, List<Order>> collect = this.queryListByPromotion(pintuanId).stream().collect(Collectors.groupingBy(Order::getParentOrderSn));

        for (Map.Entry<String, List<Order>> entry : collect.entrySet()) {
            //是否开启虚拟成团
            if (Boolean.FALSE.equals(fictitious) && CharSequenceUtil.isNotEmpty(entry.getKey()) && entry.getValue().size() < requiredNum) {
                //如果未开启虚拟成团且已参团人数小于成团人数，则自动取消订单
                String reason = "拼团活动结束订单未付款，系统自动取消订单";
                if (CharSequenceUtil.isNotEmpty(entry.getKey())) {
                    this.systemCancel(entry.getKey(), reason);
                } else {
                    for (Order order : entry.getValue()) {
                        if (!CharSequenceUtil.equalsAny(order.getOrderStatus(), OrderStatusEnum.COMPLETED.name(), OrderStatusEnum.DELIVERED.name(),
                                OrderStatusEnum.TAKE.name(), OrderStatusEnum.STAY_PICKED_UP.name())) {
                            this.systemCancel(order.getSn(), reason);
                        }
                    }
                }
            } else if (Boolean.TRUE.equals(fictitious)) {
                this.fictitiousPintuan(entry, requiredNum);
            }
        }
        return false;
    }

    @Override
    public Map<String, Long> pendingPaymentOrderNum(String supplierId) {
        Map<String, Long> map = new HashMap<>();
        //待付款订单
        Long pendingPaymentOrderNum = this.count(new LambdaQueryWrapper<Order>().eq(Order::getStoreId, supplierId).eq(Order::getOrderStatus,
                OrderStatusEnum.UNPAID.name()));
        map.put("pendingPaymentOrderNum", pendingPaymentOrderNum);
        //待发货,待收货订单
        Long deliveryAndReceiptOrderNum =
                this.count(new LambdaQueryWrapper<Order>().eq(Order::getStoreId, supplierId).and(i -> i.eq(Order::getOrderStatus,
                        OrderStatusEnum.UNDELIVERED.name()).or().eq(Order::getOrderStatus, OrderStatusEnum.DELIVERED.name())));
        map.put("deliveryAndReceiptOrderNum", deliveryAndReceiptOrderNum);
        //退款 退货订单
        Long refundAndReturnOrderNum = this.count(new LambdaQueryWrapper<Order>().eq(Order::getStoreId, supplierId).eq(Order::getOrderStatus,
                OrderStatusEnum.CANCELLED.name()));
        map.put("refundAndReturnOrderNum", refundAndReturnOrderNum);
        return map;
    }

    /**
     * 虚拟成团
     *
     * @param entry       订单列表
     * @param requiredNum 必须参团人数
     */
    @Transactional
    public void fictitiousPintuan(Map.Entry<String, List<Order>> entry, Integer requiredNum) {
        Map<String, List<Order>> listMap = entry.getValue().stream().collect(Collectors.groupingBy(Order::getPayStatus));
        //未付款订单
        List<Order> unpaidOrders = listMap.get(PayStatusEnum.UNPAID.name());
        //未付款订单自动取消
        if (unpaidOrders != null && !unpaidOrders.isEmpty()) {
            for (Order unpaidOrder : unpaidOrders) {
                this.systemCancel(unpaidOrder.getSn(), "拼团活动结束订单未付款，系统自动取消订单");
            }
        }
        List<Order> paidOrders = listMap.get(PayStatusEnum.PAID.name());
        //如待参团人数大于0，并已开启虚拟成团
        if (!paidOrders.isEmpty()) {
            //待参团人数
            int waitNum = requiredNum - paidOrders.size();
            //添加虚拟成团
            for (int i = 0; i < waitNum; i++) {
                Order order = new Order();
                BeanUtil.copyProperties(paidOrders.get(0), order, "id", "sn");
                order.setSn(SnowFlake.createStr("G"));
                order.setParentOrderSn(paidOrders.get(0).getParentOrderSn());
                order.setBuyerId("-1");
                order.setNickname("参团人员");
                order.setDeleteFlag(true);
                this.save(order);
                paidOrders.add(order);
            }
            for (Order paidOrder : paidOrders) {
                if (!CharSequenceUtil.equalsAny(paidOrder.getOrderStatus(), OrderStatusEnum.COMPLETED.name(), OrderStatusEnum.DELIVERED.name(),
                        OrderStatusEnum.TAKE.name(), OrderStatusEnum.STAY_PICKED_UP.name())) {
                    if (OrderTypeEnum.NORMAL.name().equals(paidOrder.getOrderType())) {
                        paidOrder.setOrderStatus(OrderStatusEnum.UNDELIVERED.name());
                    } else if (OrderTypeEnum.VIRTUAL.name().equals(paidOrder.getOrderType())) {
                        paidOrder.setOrderStatus(OrderStatusEnum.TAKE.name());
                    }
                    this.updateById(paidOrder);
                    orderStatusMessage(paidOrder);
                }
            }
        }
    }

    /**
     * 订单状态变更消息
     *
     * @param order 订单信息
     */
    @Transactional
    public void orderStatusMessage(Order order) {
        OrderMessage orderMessage = new OrderMessage();
        orderMessage.setOrderSn(order.getSn());
        orderMessage.setNewStatus(OrderStatusEnum.valueOf(order.getOrderStatus()));
        this.sendUpdateStatusMessage(orderMessage);
    }


    /**
     * 此方法只提供内部调用，调用前应该做好权限处理
     * 修改订单状态
     *
     * @param orderSn     订单编号
     * @param orderStatus 订单状态
     */
    private void updateStatus(String orderSn, OrderStatusEnum orderStatus) {
        this.baseMapper.updateStatus(orderStatus.name(), orderSn);
    }

    /**
     * 检测拼团订单内容
     * 此方法用与订单确认
     * 判断拼团是否达到人数进行下一步处理
     *
     * @param pintuanId     拼团活动ID
     * @param parentOrderSn 拼团父订单编号
     */
    @Transactional
    public void checkPintuanOrder(String pintuanId, String parentOrderSn) {
        //获取拼团配置
        Pintuan pintuan = promotionsClient.getPintuanVO(pintuanId);
        List<Order> list = this.getPintuanOrder(pintuanId, parentOrderSn);
        int count = list.size();
        if (count == 1) {
            //如果为开团订单，则发布一个24小时的延时任务，时间到达后，如果未成团则自动结束（未开启虚拟成团的情况下）
            PintuanOrderMessage pintuanOrderMessage = new PintuanOrderMessage();
            //开团结束时间
            long startTime = DateUtil.offsetHour(new Date(), 24).getTime();
            if (DateUtil.compare(DateUtil.offsetHour(pintuan.getStartTime(), 24), pintuan.getEndTime()) > 0) {
                startTime = pintuan.getEndTime().getTime();
            }
            pintuanOrderMessage.setOrderSn(parentOrderSn);
            pintuanOrderMessage.setPintuanId(pintuanId);

            TimeTriggerMsg timeTriggerMsg =
                    TimeTriggerMsg.builder().
                            triggerExecutor(TimeExecuteConstant.PROMOTION_EXECUTOR).
                            triggerTime(startTime).
                            param(pintuanOrderMessage).
                            uniqueKey(DelayQueueTools.wrapperUniqueKey(DelayTypeEnums.PINTUAN_ORDER, (pintuanId + parentOrderSn))).
                            exchange(amqpExchangeProperties.getPromotion()).
                            routingKey(PromotionRoutingKey.PINTUAN).build();

            this.timeTrigger.addDelay(timeTriggerMsg);
        }
        //拼团所需人数，小于等于 参团后的人数，则说明成团，所有订单成团
        if (pintuan.getRequiredNum() <= count) {
            this.pintuanOrderSuccess(list);
        }
    }

    /**
     * 根据拼团活动id和拼团订单sn获取所有当前与当前拼团订单sn相关的订单
     *
     * @param pintuanId     拼团活动id
     * @param parentOrderSn 拼团订单sn
     * @return 所有当前与当前拼团订单sn相关的订单
     */
    private List<Order> getPintuanOrder(String pintuanId, String parentOrderSn) {
        //寻找拼团的所有订单
        LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Order::getPromotionId, pintuanId).eq(Order::getOrderPromotionType, OrderPromotionTypeEnum.PINTUAN.name()).eq(Order::getPayStatus, PayStatusEnum.PAID.name());
        //拼团sn=开团订单sn 或者 参团订单的开团订单sn
        queryWrapper.and(i -> i.eq(Order::getSn, parentOrderSn).or(j -> j.eq(Order::getParentOrderSn, parentOrderSn)));
        //参团后的订单数（人数）
        return this.list(queryWrapper);
    }

    /**
     * 根据提供的拼团订单列表更新拼团状态为拼团成功
     * 循环订单列表根据不同的订单类型进行确认订单
     *
     * @param orderList 需要更新拼团状态为成功的拼团订单列表
     */
    @Transactional
    public void pintuanOrderSuccess(List<Order> orderList) {
        for (Order order : orderList) {
            if (order.getOrderType().equals(OrderTypeEnum.VIRTUAL.name())) {
                this.virtualOrderConfirm(order.getSn());
            } else if (order.getOrderType().equals(OrderTypeEnum.NORMAL.name())) {
                this.normalOrderConfirm(order.getSn());
            }
        }
    }

    /**
     * 根据提供的拼团订单列表更新拼团状态为拼团失败
     *
     * @param list 需要更新拼团状态为失败的拼团订单列表
     */
    private void pintuanOrderFailed(List<Order> list) {
        for (Order order : list) {
            try {
                this.systemCancel(order.getSn(), "拼团人数不足，拼团失败！");
            } catch (Exception e) {
                log.error("拼团订单取消失败", e);
            }
        }
    }


    /**
     * 检查交易信息
     *
     * @param tradeDTO 交易DTO
     */
    private void checkTradeDTO(TradeDTO tradeDTO) {
        //检测是否为拼团订单
        if (tradeDTO.getParentOrderSn() != null) {
            //判断用户不能参与自己发起的拼团活动
            LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Order::getSn, tradeDTO.getParentOrderSn());
            Order parentOrder = this.getOne(queryWrapper, false);
            if (parentOrder.getBuyerId().equals(UserContext.getCurrentUser().getExtendId())) {
                throw new ServiceException(ResultCode.PINTUAN_JOIN_ERROR);
            }
        }
    }

    /**
     * 普通商品订单确认
     * 修改订单状态为待发货
     * 发送订单状态变更消息
     *
     * @param orderSn 订单编号
     */
//    @Transactional
    @ShardingTransactionType(TransactionType.BASE)
    public void normalOrderConfirm(String orderSn) {
        //修改订单
        //查询订单状态
        Order bySn = this.getBySn(orderSn);
        if(bySn!=null&&!OrderStatusEnum.DELIVERED.name().equals(bySn.getOrderStatus())){
            this.update(new LambdaUpdateWrapper<Order>().eq(Order::getSn, orderSn).set(Order::getOrderStatus, OrderStatusEnum.UNDELIVERED.name()));
        }
        //修改订单
        OrderMessage orderMessage = new OrderMessage();
        orderMessage.setNewStatus(OrderStatusEnum.UNDELIVERED);
        orderMessage.setOrderSn(orderSn);
        this.sendUpdateStatusMessage(orderMessage);
    }

    /**
     * 虚拟商品订单确认
     * 修改订单状态为待核验
     * 发送订单状态变更消息
     *
     * @param orderSn 订单编号
     */
    @Transactional
    public void virtualOrderConfirm(String orderSn) {
        //修改订单
        this.update(new LambdaUpdateWrapper<Order>().eq(Order::getSn, orderSn).set(Order::getOrderStatus, OrderStatusEnum.TAKE.name()));
        OrderMessage orderMessage = new OrderMessage();
        orderMessage.setNewStatus(OrderStatusEnum.TAKE);
        orderMessage.setOrderSn(orderSn);
        this.sendUpdateStatusMessage(orderMessage);
    }

    /**
     * 检测虚拟订单信息
     *
     * @param order            订单
     * @param verificationCode 验证码
     */
    private void checkVerificationOrder(Order order, String verificationCode) {
        //判断查询是否可以查询到订单
        if (order == null) {
            throw new ServiceException(ResultCode.ORDER_NOT_EXIST);
        }
        //判断是否为虚拟订单
        if (!order.getOrderType().equals(OrderTypeEnum.VIRTUAL.name())) {
            throw new ServiceException(ResultCode.ORDER_TAKE_ERROR);
        }
        //判断虚拟订单状态
        if (!order.getOrderStatus().equals(OrderStatusEnum.TAKE.name())) {
            throw new ServiceException(ResultCode.ORDER_TAKE_ERROR);
        }
        //判断验证码是否正确
        if (!verificationCode.equals(order.getVerificationCode())) {
            throw new ServiceException(ResultCode.ORDER_TAKE_ERROR);
        }
    }

    /**
     * 壹邦玖回调
     *  message_type:
         *  goods.alter:商品修改
         *  goods.on.sale:上架
         *  goods.undercarriage:下架
         *  goods.delete:商品删除
         *  order.cancel:订单取消
         *  order.delivery:订单发货
         *  order.sending:订单部分发货消息 （中台版本号>1.1.588 ）
         *  order.update_send:订单修改物流
         *  after_sales.pass 售后审核成功
         *  after_sales.reject 售后审核驳回
         *  after_sales.receiving 售后确认收货 （如果是换货，这时候也代表发货了 中台版本号需大于等于1.1.606）
         *  after_sales.complete 售后确认退款
     * order_sn：下单时传给中台的订单号
     * product_id：中台的商品id
     * member_sign: 用来区别是哪个中台供应链推送过来的消息
     * @param callBackVO 参数
     */

    @Override
    public ResponseBean callback(CallBackVO callBackVO) {
        log.info("callBackVO == {}" ,JSONObject.toJSONString(callBackVO));
        return orderFactory.execute(callBackVO);
    }

    String str = "https://supply.yibangjiu.com/supplyapi";

    public String getToken() {
        Object token = redisTemplate.boundValueOps("yunxin_token").get();
        if (token != null) {
            return (String) token;
        }
        String tokenUrl = str + "/app/application/getToken";
        Map<String, Object> params = new HashMap<>();
        params.put("app_key", "application4");
        params.put("app_secret", "a7c5dbc8aaa6a67bc2a73b1d71faeb91");
        HttpRequest post1 = HttpUtil.createPost(tokenUrl).body(JSONObject.toJSONString(params));
        String body = post1.execute().body();
        JSONObject jsonObject = JSONObject.parseObject(body);
        if (jsonObject.getInteger("code") != 0) {
            throw new ServiceException("token获取失败");
        }
        redisTemplate.boundValueOps("yunxin_token").set(jsonObject.getJSONObject("data").getString("token"));
        redisTemplate.expire("yunxin_token", 30, TimeUnit.MINUTES);
        return jsonObject.getJSONObject("data").getString("token");
    }


    /**
     * 下单前校验能否下单
     * @param beforeCheckVO 下单信息，与地址
     * @return 能否下单(有运费即可下单)
     */
    @Override
    public JSONObject beforeCheck(BeforeCheckVO beforeCheckVO) {
        Map<String, Object> params = new HashMap<>();

        Map<String, Object> addressMap = new HashMap<>();
        addressMap.put("area", beforeCheckVO.getArea());
        addressMap.put("city", beforeCheckVO.getCity());
        addressMap.put("consignee", beforeCheckVO.getConsignee());
        addressMap.put("description", beforeCheckVO.getDescription());
        addressMap.put("phone", beforeCheckVO.getPhone());
        addressMap.put("province", beforeCheckVO.getProvince());
        addressMap.put("street", beforeCheckVO.getStreet());
        params.put("address", addressMap);

        params.put("spu", beforeCheckVO.getSpuVOList());

        String token = this.getToken();
        HttpRequest httpRequest = HttpUtil.createPost(str + "/app/order/beforeCheck").header("x-token", token).body(JSONObject.toJSONString(params));
        String body = httpRequest.execute().body();
        JSONObject jsonObject = JSONObject.parseObject(body);
//        if (jsonObject.getInteger("code") != 0) {
//            throw new ServiceException("获取订单验证异常");
//        }
//        BeforeCheckRes beforeCheckRes = (BeforeCheckRes) jsonObject.get("data");
        return jsonObject;
    }


    /**
     * 调用壹邦玖供应链，下单并扣款。
     * @param order 订单号
     */
    private void payAppOrder(Order order) {
        log.info("order == {}", JSONObject.toJSONString(order));
        List<OrderItem> orderItemList = orderItemService.getByOrderSn(order.getSn());
        log.info("orderItemList == {}", JSONObject.toJSONString(orderItemList));
        //每个子订单创建一个，订单。
        for (OrderItem orderItem : orderItemList) {
            List<SpuVO> spuVOList = new ArrayList<>();
            BeforeCheckVO beforeCheckVO = new BeforeCheckVO();
            String sn = orderItem.getSn();

            GoodsSku goodsSku = goodsSkuClient.getGoodsSkuById(orderItem.getSkuId());
            log.info("goodsSku == {}", JSONObject.toJSONString(goodsSku));
            if (goodsSku == null) {
                continue;
            }
            if (Integer.valueOf(1).equals(goodsSku.getThirdPartyPlatformType())) {
                SpuVO spuVO = new SpuVO();
                spuVO.setNumber(orderItem.getNum());
                spuVO.setSku(Long.valueOf(goodsSku.getThirdPartyPlatformId()));
                spuVOList.add(spuVO);
            }
            //不为空，则表示存在供应链的数据
            if (CollectionUtil.isNotEmpty(spuVOList)) {
                this.conversionAddress(beforeCheckVO, order.getConsigneeAddressIdPath());
                beforeCheckVO.setPhone(order.getConsigneeMobile());
                beforeCheckVO.setConsignee(order.getConsigneeName());
                beforeCheckVO.setDescription(order.getConsigneeDetail());
                JSONObject jsonObject = this.appOrder(spuVOList, beforeCheckVO, sn, "下单并支付");
                if (jsonObject.getInteger("code") != 0) {
                    //如果此子订单已有异常信息着不进行添加
                    OrderItemError updateOrderItemError = orderItemErrorService.getOne(new LambdaQueryWrapper<OrderItemError>().eq(OrderItemError::getItemOrderSn, sn).orderByDesc(OrderItemError::getCreateTime).last("limit 1"));
                    if (updateOrderItemError != null && StringUtils.isNotEmpty(updateOrderItemError.getId())) {
                        updateOrderItemError.setReCount(updateOrderItemError.getReCount() == null ? 0 : updateOrderItemError.getReCount() + 1);
                        orderItemErrorService.updateById(updateOrderItemError);
                        return;
                    }
                    OrderItemError orderItemError = new OrderItemError();
                    BeanUtil.copyProperties(beforeCheckVO, orderItemError);
                    orderItemError.setItemOrderSn(sn);
                    orderItemError.setOrderNum(spuVOList.get(0).getNumber());
                    orderItemError.setThirdPartyPlatformId(String.valueOf(spuVOList.get(0).getSku()));
                    orderItemError.setGoodsId(goodsSku.getGoodsId());
                    orderItemError.setSkuId(goodsSku.getId());
                    orderItemError.setReCount(0);
                    orderItemError.setMsg(jsonObject.getJSONObject("data").getString("messages"));
                    orderItemErrorService.save(orderItemError);
                    return;
//                    throw new ServiceException("供应链生成订单异常");
                }
                //供应链 交易成功
                log.info("dataVo == {}" , JSONObject.toJSONString(jsonObject.get("data")));
                DataVO dataVO = JSONObject.parseObject(JSONObject.toJSONString(jsonObject.get("data")),DataVO.class);
                orderItem.setOrderJsonVal(JSONObject.toJSONString(dataVO));
                for (OrdersVO dataVOOrder : dataVO.getOrders()) {
                    if (CollectionUtil.isNotEmpty(dataVOOrder.getOrder_items()) && dataVOOrder.getOrder_items().get(0).getId()!=null) {
                        orderItem.setSupplyChainOrderId(String.valueOf(dataVOOrder.getOrder_items().get(0).getId()));
                    }
                }
                orderItem.setOrderItemIdVal(String.valueOf(dataVO.getOrders().get(0).getOrder_sn()));
                orderItemService.updateById(orderItem);

                //成功了将异常信息删除
                LambdaUpdateWrapper<OrderItemError> updateWrapper = new LambdaUpdateWrapper<>();
                updateWrapper.set(OrderItemError::getDeleteFlag, true);
                updateWrapper.eq(OrderItemError::getItemOrderSn, sn);
                orderItemErrorService.update(updateWrapper);
            }
        }
    }


    /**
     * 定时重试下单接口(十分钟每次，并且是整点)
     */
    @Scheduled(cron = "0 0/10 * * * *")
    public void timedRetry() {
        RLock lock = null;
        try {
            lock = redisson.getLock(LockPrefix.WALLET.getPrefix());
            lock.lock(100, TimeUnit.SECONDS);

            List<OrderItemError> orderItemErrors = orderItemErrorService.list(new LambdaQueryWrapper<OrderItemError>()
                    .eq(OrderItemError::getDeleteFlag, false)
                    //查询最近三天，和重试次数不足5次的数据
                    .and(q ->
                            q.between(OrderItemError::getCreateTime, LocalDateTime.now().minusDays(3), LocalDateTime.now())
                            .or().le(OrderItemError::getReCount, 5)
                    )
            );

            for (OrderItemError orderItemError : orderItemErrors) {
                OrderItem orderItem = orderItemService.getBySn(orderItemError.getItemOrderSn());
                log.info("orderItem=={}", JSONObject.toJSONString(orderItem));
                if (orderItem == null) {
                    continue;
                }
                Order order = this.getBySn(orderItem.getOrderSn());
                log.info("order=={}", JSONObject.toJSONString(order));
                if (order == null) {
                    continue;
                }
                this.payAppOrder(order);
            }
        } catch (Exception e) {
            log.error("error == {}",e.getMessage());
            e.printStackTrace();
        } finally {
            if (lock != null) {
                lock.unlock();
                log.info("强制释放锁");
            }
        }
    }

    @Override
    public JSONObject appOrder(List<SpuVO> spuVOList, BeforeCheckVO beforeCheckVO, String orderSn, String remark) {
        Map<String, Object> params = new HashMap<>();
        params.put("spu", spuVOList);

        Map<String, Object> addressMap = new HashMap<>();
        addressMap.put("area", beforeCheckVO.getArea());
        addressMap.put("city", beforeCheckVO.getCity());
        addressMap.put("consignee", beforeCheckVO.getConsignee());
        addressMap.put("description", beforeCheckVO.getDescription());
        addressMap.put("phone", beforeCheckVO.getPhone());
        addressMap.put("province", beforeCheckVO.getProvince());
        addressMap.put("street", beforeCheckVO.getStreet());
        params.put("address", addressMap);
        params.put("order_sn", orderSn);
        params.put("remark", remark);

        String token = this.getToken();
        System.out.println("JSONObject.toJSONString(params) = " + JSONObject.toJSONString(params));
        HttpRequest httpRequest = HttpUtil.createPost(str + "/app/order").header("x-token", token).body(JSONObject.toJSONString(params));
        String body = httpRequest.execute().body();
        log.info("appOrder  body == {}", body);
        JSONObject jsonObject = new JSONObject();
        try {
            jsonObject = JSONObject.parseObject(body);
        } catch (Exception e) {
            log.info("message == {}", e.getMessage());
            jsonObject = new JSONObject();
            jsonObject.put("code", 500);
            return jsonObject;
        }
        return jsonObject;
    }



    /**
     * 申请售后
     * @return 售后信息
     */
    public JSONObject appAfterSalesCreate(AppAfterSalesCreate appAfterSalesCreate, String orderStatus, AfterSale afterSale) {
        JSONObject orderDetailJson = this.orderDetailByThirdOrderSn(appAfterSalesCreate.getThird_order_sn());
        if (orderDetailJson.getInteger("code") != 0) {
            log.error("getThird_order_sn == {},  errMessage == {}", appAfterSalesCreate.getThird_order_sn() , orderDetailJson.get("msg"));
            throw new ServiceException("供应链，未获取到订单详情");
        }
        JSONObject data = orderDetailJson.getJSONObject("data");
        JSONArray read = data.getJSONArray("read");
        for (Object o : read) {
            JSONObject jsonObject1 = (JSONObject) o;
            System.out.println("o = " + jsonObject1.get("technical_services_fee"));
            System.out.println("o = " + jsonObject1.get("freight"));
            appAfterSalesCreate.setFreight(jsonObject1.getInteger("freight"));
            appAfterSalesCreate.setTechnical_services_fee(jsonObject1.getInteger("technical_services_fee"));
        }

        Map<String, Object> params = new HashMap<>();
        params.put("third_order_sn", appAfterSalesCreate.getThird_order_sn());
        params.put("order_item_id", appAfterSalesCreate.getOrder_item_id());
        params.put("reason_type", 5);
        params.put("refund_way", 0);
        //TODO 此处待确认
        params.put("is_received", 0);
        if (orderStatus.equals(OrderStatusEnum.UNDELIVERED.name())) {
            params.put("refund_type", 0);
        } else {
            //退货
            if (afterSale!= null && AfterSaleTypeEnum.RETURN_GOODS.name().equals(afterSale.getServiceType())) {
                params.put("refund_type", 1);
            }
            //退款
            if (afterSale!= null && AfterSaleTypeEnum.RETURN_MONEY.name().equals(afterSale.getServiceType())) {
                params.put("refund_type", 0);
            }
            if (afterSale!= null && afterSale.getNum()!= null && afterSale.getNum()>0) {
                params.put("refund_way", 1);
                params.put("num", afterSale.getNum());
            }
        }
        params.put("freight", appAfterSalesCreate.getFreight());
        params.put("technical_services_fee", appAfterSalesCreate.getTechnical_services_fee());


        String token = this.getToken();
        HttpRequest httpRequest = HttpUtil.createPost(str + "/app/afterSales/create").header("x-token", token).body(JSONObject.toJSONString(params));
        String body = httpRequest.execute().body();
        log.info("body == {} ", body);
        JSONObject jsonObject = JSONObject.parseObject(body);
        if (jsonObject.getInteger("code") != 0) {
//            if (jsonObject.getString("msg").equals("已退款,无需售后")) {
//                throw new ServiceException("请联系官方客服处理");
//            }
            log.error("请联系官方客服处理 == {}, third_order_sn=={}, order_item_id =={}", jsonObject.toJSONString(), appAfterSalesCreate.getThird_order_sn(), appAfterSalesCreate.getOrder_item_id());
            throw new ServiceException("请联系官方客服处理");
        }
        return jsonObject;
    }

    /**
     * 取消售后
     * @return 取消售后
     */
    @Override
    public JSONObject afterSalesClose(OrderItem orderItem) {
        GoodsSku goodsSku = goodsSkuClient.getGoodsSkuById(orderItem.getSkuId());
        if (goodsSku == null) {
            log.error("未获取到sku == {} ",  orderItem.getSkuId());
            return new JSONObject();
        }
        if (goodsSku.getThirdPartyPlatformType() != null && goodsSku.getThirdPartyPlatformType() == 1) {
            Map<String, Object> params = new HashMap<>();
            params.put("id", orderItem.getAfterSalesId());

            String token = this.getToken();
            HttpRequest httpRequest = HttpUtil.createPost(str + "/app/afterSales/close").header("x-token", token).body(JSONObject.toJSONString(params));
            String body = httpRequest.execute().body();
            JSONObject jsonObject = JSONObject.parseObject(body);
            if (jsonObject.getInteger("code") != 0) {
                throw new ServiceException("订单取消售后失败");
            }
            return jsonObject;
        }
        return new JSONObject();
    }

    /**
     * 售后发货
     * @return 售后发货
     */
    @Override
    public JSONObject afterSalesSend(OrderItem orderItem, String company_name, String company_code, String express_no) {
        GoodsSku goodsSku = goodsSkuClient.getGoodsSkuById(orderItem.getSkuId());
        if (goodsSku == null) {
            log.error("未获取到sku 11 == {}" , orderItem.getSkuId());
            return new JSONObject();
        }
        if (goodsSku.getThirdPartyPlatformType()!=null && goodsSku.getThirdPartyPlatformType() == 1) {
            JSONObject shopAddressByOrderId = this.findShopAddressByOrderId(orderItem.getAfterSalesId());
            log.info("shopAddressByOrderId == {}", JSONObject.toJSONString(shopAddressByOrderId));

            Map<String, Object> params = new HashMap<>();
            params.put("after_sales_id", orderItem.getAfterSalesId());
            params.put("company_name", company_name);
            params.put("company_code", company_code);
            params.put("express_no", express_no);
            params.put("shipping_address_id", shopAddressByOrderId.getJSONObject("data").getInteger("id"));

            String token = this.getToken();
            HttpRequest httpRequest = HttpUtil.createPost(str + "/app/afterSales/send").header("x-token", token).body(JSONObject.toJSONString(params));
            String body = httpRequest.execute().body();
            JSONObject jsonObject = JSONObject.parseObject(body);
            if (jsonObject.getInteger("code") != 0) {
                throw new ServiceException("售后发货失败");
            }
            return jsonObject;
        }
        return new JSONObject();
    }


    /**
     * 通过售后id获取默认商家售后退货地址
     *
     * @return 通过售后id获取默认商家售后退货地址
     */
    public JSONObject findShopAddressByOrderId(Integer id) {
        String token = this.getToken();
        HttpRequest httpRequest = HttpUtil.createGet(str + "/app/supplier/findShopAddressByOrderId?after_sales_id=" + id).header("x-token", token);
        String body = httpRequest.execute().body();
        log.info("findShopAddressByOrderId == {} ", body);
        JSONObject jsonObject = JSONObject.parseObject(body);
        if (jsonObject.getInteger("code") != 0) {
            throw new ServiceException("通过售后id获取默认商家售后退货地址失败");
        }
        return jsonObject;
    }
    /**
     * 确认收货
     *
     * @return 确认收货
     */
    public JSONObject receive(OrderItem orderItem) {
        GoodsSku goodsSku = goodsSkuClient.getGoodsSkuById(orderItem.getSkuId());
        if (goodsSku == null) {
            log.error("未获取到sku信息==={}", orderItem.getSkuId());
            return new JSONObject();
        }
        //壹邦玖确认收货
        if (goodsSku.getThirdPartyPlatformType() != null && goodsSku.getThirdPartyPlatformType() == 1) {
            Map<String, Object> params = new HashMap<>();
            params.put("third_order_sn", orderItem.getSn());

            String token = this.getToken();
            HttpRequest httpRequest = HttpUtil.createPost(str + "/app/order/receive").header("x-token", token).body(JSONObject.toJSONString(params));
            String body = httpRequest.execute().body();
            log.info("确认收货 body == {}", body);
            JSONObject jsonObject = JSONObject.parseObject(body);
            if (jsonObject.getInteger("code") != 0) {
                String msg = jsonObject.getString("msg");
                //供应链已关闭的话，就不做限制，让他到已完成状态去。
                if ("已关闭的订单无法收货".equals(msg)) {
                    return new JSONObject();
                }
                throw new ServiceException(jsonObject.getString("msg"));
            }
            return jsonObject;
        }
        return new JSONObject();
    }
    /**
     * 取消售后
     * @return 取消售后
     */
    public JSONObject afterSalesClose(Integer id) {
        Map<String, Object> params = new HashMap<>();
        params.put("id", id);

        String token = this.getToken();
        HttpRequest httpRequest = HttpUtil.createPost(str + "/app/afterSales/close").header("x-token", token).body(JSONObject.toJSONString(params));
        String body = httpRequest.execute().body();
        JSONObject jsonObject = JSONObject.parseObject(body);
        if (jsonObject.getInteger("code") != 0) {
            throw new ServiceException("订单取消售后失败");
        }
        return jsonObject;
    }

    /**
     * 售后发货
     * @return 售后发货
     */
    public JSONObject afterSalesSend(Integer after_sales_id, String company_name, String company_code, String express_no) {
        JSONObject shopAddressByOrderId = this.findShopAddressByOrderId(after_sales_id);
        log.info("shopAddressByOrderId == {}", shopAddressByOrderId.toJSONString());

        Map<String, Object> params = new HashMap<>();
        params.put("after_sales_id", after_sales_id);
        params.put("company_name", company_name);
        params.put("company_code", company_code);
        params.put("express_no", express_no);
        params.put("shipping_address_id", shopAddressByOrderId.getJSONObject("data").getInteger("id"));

        String token = this.getToken();
        HttpRequest httpRequest = HttpUtil.createPost(str + "/app/afterSales/close").header("x-token", token).body(JSONObject.toJSONString(params));
        String body = httpRequest.execute().body();
        JSONObject jsonObject = JSONObject.parseObject(body);
        if (jsonObject.getInteger("code") != 0) {
            throw new ServiceException("订单取消售后失败");
        }
        return jsonObject;
    }

    /**
     * 确认收货
     *
     * @return 确认收货
     */
    public JSONObject receive(String  third_order_sn) {
        Map<String, Object> params = new HashMap<>();
        params.put("third_order_sn", third_order_sn);

        String token = this.getToken();
        HttpRequest httpRequest = HttpUtil.createPost(str + "/app/order/receive").header("x-token", token).body(JSONObject.toJSONString(params));
        String body = httpRequest.execute().body();
        JSONObject jsonObject = JSONObject.parseObject(body);
        if (jsonObject.getInteger("code") != 0) {
            throw new ServiceException("确认收货失败");
        }
        return jsonObject;
    }

    /**
     * 修改物流地址
     *
     * @return 修改物流地址
     */
    public JSONObject updateShippingAddress(Order order,String itemSn) {
        Map<String, Object> params = new HashMap<>();
        params.put("order_sn", itemSn);

        AddressVO addressVO = new AddressVO();
        addressVO.setConsignee(order.getConsigneeName());
        String[] split = order.getConsigneeAddressPath().split(",");
        if (split.length > 0) {
            if (StringUtils.isNotEmpty(split[0])) {
                addressVO.setProvince(split[0]);
            }
            if (StringUtils.isNotEmpty(split[1])) {
                addressVO.setCity(split[1]);
            }
            if (StringUtils.isNotEmpty(split[2])) {
                addressVO.setArea(split[2]);
            }
            if (split.length > 3 && StringUtils.isNotEmpty(split[3])) {
                addressVO.setStreet(split[3]);
            }
        }
        addressVO.setPhone(order.getConsigneeMobile());
        addressVO.setConsignee(order.getConsigneeName());
        addressVO.setDescription(order.getConsigneeDetail());

        params.put("address", addressVO);

        log.info("params == {}", JSONObject.toJSONString(params));
        String token = this.getToken();
        HttpRequest httpRequest = HttpUtil.createPost(str + "/app/order/updateShippingAddress").header("x-token", token).body(JSONObject.toJSONString(params));
        String body = httpRequest.execute().body();
        log.info("body == {}" , body);
        JSONObject jsonObject = JSONObject.parseObject(body);
        if (jsonObject.getInteger("code") != 0) {
            throw new ServiceException("修改物流地址失败");
        }
        return jsonObject;
    }

    public void updateAddress(Order order) {
        List<OrderItem> orderItemList = orderItemService.getByOrderSn(order.getSn());
        for (OrderItem orderItem : orderItemList) {
            updateShippingAddress(order, orderItem.getSn());
        }
    }

    public JSONObject orderDetailByThirdOrderSn(String orderSn) {
        String token = this.getToken();
        HttpRequest httpRequest = HttpUtil.createGet(str + "/app/order/orderDetailByThirdOrderSn?third_order_sn="+orderSn).header("x-token", token);
        String body = httpRequest.execute().body();
        JSONObject jsonObject = JSONObject.parseObject(body);
        return jsonObject;
    }

    /**
     * 省钱计算器
     *
     * @return 本周省钱金额
     */
    @Override
    public ResultMessage<Object> vipComputePrice() {
        //会员特价，省钱金额
        LambdaQueryWrapper<OrderItem> orderLambdaQueryWrapper = this.createQueryWrapper();
        orderLambdaQueryWrapper.ge(OrderItem::getCreateTime, DateUtil.offsetDay(DateUtil.date(), -7));
        List<OrderItem> itemList = orderItemService.list(orderLambdaQueryWrapper);
        return ResultUtil.data(this.resultMap(itemList));
    }

    public Map<String, Object> resultMap(List<OrderItem> itemList) {
        Map<String, Object> resultMap = new HashMap<>();
        if (CollectionUtil.isEmpty(itemList)) {
            resultMap.put("greenPrice", 0);
            resultMap.put("vipPrice", 0D);
            return resultMap;
        }
        BigDecimal flowPrice = BigDecimal.valueOf(0);
        BigDecimal originalPrice = BigDecimal.valueOf(0);
        List<String> skuIdList = itemList.stream().map(OrderItem::getSkuId).toList();
        List<GoodsSku> goodsSkus = goodsSkuClient.getGoodsSkuByIdFromCache(skuIdList);
        for (OrderItem orderItem : itemList) {
            flowPrice = flowPrice.add(BigDecimal.valueOf(orderItem.getFlowPrice()));
            originalPrice = originalPrice.add(BigDecimal.valueOf(orderItem.getSubTotal()));
            Double greenScore = 0D;
            if (CollectionUtil.isNotEmpty(goodsSkus)) {
                for (GoodsSku goodsSku : goodsSkus) {
                    if (goodsSku != null && StringUtils.isNotEmpty(orderItem.getSkuId()) && orderItem.getSkuId().equals(goodsSku.getId())) {
                        greenScore = goodsSku.getGreenScore();
                    }
                }
            }
            BigDecimal numScore = BigDecimal.valueOf(greenScore).multiply(BigDecimal.valueOf(orderItem.getNum()));
            originalPrice = originalPrice.add(numScore);
//            originalPrice = originalPrice.multiply(BigDecimal.valueOf(orderItem.getNum()));
        }
        BigDecimal vipPrice = originalPrice.subtract(flowPrice);
        resultMap.put("vipPrice", vipPrice.doubleValue());

        //绿色积分劵，待下个版本处理
        ComputeDTO computeDTO = new ComputeDTO();
        computeDTO.builderCompute(UserContext.getCurrentId());
        orderComputeEventFactory.execute(computeDTO);
        resultMap.put("greenPrice", computeDTO.getGreenPrice());
        resultMap.put("greenList",computeDTO.getGreenList());
        return resultMap;
    }

    /**
     * 合计金额
     *
     * @return 用户的合计省钱金额
     */
    @Override
    public Map<String, Object> sumPrice() {
        LambdaQueryWrapper<OrderItem> orderLambdaQueryWrapper = this.createQueryWrapper();
        List<OrderItem> itemList = orderItemService.list(orderLambdaQueryWrapper);
        return this.resultMap(itemList);
    }


    @Override
    public void conversionAddress(BeforeCheckVO checkRes, String idPath) {
        String[] split = idPath.split(",");
        if (split.length > 0) {
            //由于壹邦玖供应链层级与系统层级不一致，按对方的来
            Map<Integer, String> map = new HashMap<>();
            RegionYbj regionYbj = null;
            if (split.length > 3) {
                regionYbj = regionYbjClient.getRegionYbjById(split[3]);
            } else {
                regionYbj = regionYbjClient.getRegionYbjById(split[2]);
            }
            this.addMap(map, regionYbj);

            for (Map.Entry<Integer, String> entry : map.entrySet()) {
                if (Integer.valueOf(1).equals(entry.getKey())) {
                    checkRes.setProvince(entry.getValue());
                }
                if (Integer.valueOf(2).equals(entry.getKey())) {
                    checkRes.setCity(entry.getValue());
                }
                if (Integer.valueOf(3).equals(entry.getKey())) {
                    checkRes.setArea(entry.getValue());
                }
                if (Integer.valueOf(4).equals(entry.getKey())) {
                    checkRes.setStreet(entry.getValue());
                }
            }
        }
    }
    /**
     * 省钱订单
     *
     * @return 省钱订单
     */
    @Override
    public ResultMessage<Object> vipOrderPrice(OrderSearchParams orderSearchParams) {
        LambdaQueryWrapper<OrderItem> queryWrapper = this.createQueryWrapper();
        queryWrapper.ge(OrderItem::getCreateTime, DateUtil.offsetDay(DateUtil.date(), -7));
        Page<OrderItem> orderItemPage = orderItemService.page(new Page<>(orderSearchParams.getPageNumber(), orderSearchParams.getPageSize()), queryWrapper);
        return this.conversion(orderItemPage);
    }

    private ResultMessage<Object> conversion(Page<OrderItem> orderItemPage) {
        if (CollectionUtil.isEmpty(orderItemPage.getRecords())) {
            return ResultUtil.data(orderItemPage);
        }
        List<String> skuIdList = orderItemPage.getRecords().stream().map(OrderItem::getSkuId).toList();
        List<GoodsSku> goodsSkus = goodsSkuClient.getGoodsSkuByIdFromCache(skuIdList);
        Page<OrderItemPriceVO> page = new Page<>();
        BeanUtil.copyProperties(orderItemPage, page);
        List<OrderItemPriceVO> itemVOList = new ArrayList<>();
        for (OrderItem orderItem : orderItemPage.getRecords()) {
            OrderItemPriceVO orderItemVO = new OrderItemPriceVO();
            BeanUtil.copyProperties(orderItem, orderItemVO);
            Double greenScore = 0D;
            if (CollectionUtil.isNotEmpty(goodsSkus)) {
                for (GoodsSku goodsSku : goodsSkus) {
                    if (goodsSku != null && StringUtils.isNotEmpty(orderItem.getSkuId()) && orderItem.getSkuId().equals(goodsSku.getId())) {
                        greenScore = goodsSku.getGreenScore();
                    }
                }
            }
//            double price = BigDecimal.valueOf(orderItem.getOriginalPrice()).add(BigDecimal.valueOf(greenScore)).subtract(BigDecimal.valueOf(orderItem.getFlowPrice())).doubleValue();
            double price = BigDecimal.valueOf(orderItem.getSubTotal()).subtract(BigDecimal.valueOf(orderItem.getFlowPrice())).doubleValue();
            price = price + (greenScore * orderItem.getNum());
            orderItemVO.setAmount(price);
            orderItemVO.setIsVipPrice(true);

            orderItemVO.setGoodsPrice(orderItemVO.getFlowPrice());
            double originalPrice = BigDecimal.valueOf(orderItem.getOriginalPrice()).add(BigDecimal.valueOf(greenScore)).doubleValue();
            orderItemVO.setOriginalPrice(BigDecimal.valueOf(originalPrice).multiply(BigDecimal.valueOf(orderItem.getNum())).doubleValue());

            itemVOList.add(orderItemVO);
        }

        page.setRecords(itemVOList);
        return ResultUtil.data(page);
    }

    public LambdaQueryWrapper<OrderItem> createQueryWrapper() {
        LambdaQueryWrapper<OrderItem> orderItemLambdaQueryWrapper = new LambdaQueryWrapper<>();

        LambdaQueryWrapper<Order> orderLambdaQueryWrapper = new LambdaQueryWrapper<>();
        orderLambdaQueryWrapper.eq(Order::getBuyerId, UserContext.getCurrentId());
        orderLambdaQueryWrapper.eq(Order::getPayStatus, PayStatusEnum.PAID.name());
        orderLambdaQueryWrapper.notIn(Order::getOrderStatus, OrderStatusEnum.CANCELLED.name(),OrderStatusEnum.CANCELLED_LODING.name(),OrderStatusEnum.UNPAID.name(),OrderStatusEnum.SUBJECT_TO_SALE.name());
        orderLambdaQueryWrapper.select(Order::getId,Order::getSn);
        List<Order> orderList = super.list(orderLambdaQueryWrapper);
        if (CollectionUtil.isEmpty(orderList)) {
            orderItemLambdaQueryWrapper.eq(OrderItem::getId, -1);
        } else {
            orderItemLambdaQueryWrapper.in(OrderItem::getOrderSn, orderList.stream().map(Order::getSn).collect(Collectors.toList()));
        }

        orderItemLambdaQueryWrapper.eq(OrderItem::getIsVipPrice, Boolean.TRUE);
        orderItemLambdaQueryWrapper.orderByDesc(OrderItem::getCreateTime);
        orderItemLambdaQueryWrapper.eq(OrderItem::getCreateBy, UserContext.getCurrentUser().getUsername());
        orderItemLambdaQueryWrapper.select(OrderItem::getId,OrderItem::getOriginalPrice, OrderItem::getGoodsPrice, OrderItem::getFlowPrice, OrderItem::getSkuId,
                OrderItem::getNum, OrderItem::getCreateTime, OrderItem::getSn, OrderItem::getGoodsName, OrderItem::getImage, OrderItem::getSubTotal);
        return orderItemLambdaQueryWrapper;
    }

    /**
     * 已最下面的地址，依次递增往上找
     *
     * @param map       层级
     * @param regionYbj 地址
     */
    public void addMap(Map<Integer, String> map, RegionYbj regionYbj) {
        if (regionYbj == null || regionYbj.getId() == null) {
            return;
        }
        map.put(regionYbj.getLevel(), regionYbj.getName());
        RegionYbj ybjById = regionYbjClient.getRegionYbjByYbjId(String.valueOf(regionYbj.getParentId()));
        if (ybjById != null && ybjById.getId() != null) {
            addMap(map, ybjById);
        }
    }

    /**
     * 回收奖券
     * @param id 订单ID
     * @param remark 备注
     *
     * @return 是否成功
     */
    @Override
    @Transactional
    @ShardingTransactionType(TransactionType.BASE)
    public ResultMessage<Object> recycle(String id, String remark) {
        Order order = new Order();
        order.setId(id);
        order.setRemark(remark);
        order.setRecycleStatus(DictConstant.RECYCLE_STATUS_01);
        super.updateById(order);

        return ResultUtil.data(boxLotteryTicketClient.recycle(id, remark));
    }

    /**
     * 根据订单统计店铺销量排名
     * @return
     */
    @Override
    public Page<StoreSaleTopVO> saleRankByOrder (StoreSaleTopParams params) {
        LocalDate date = LocalDate.now();
        if (StringUtils.isNotEmpty(params.getDate())) {
            date = LocalDate.parse(params.getDate(), DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        }
        // 当月第一天
        LocalDate start = date.with(TemporalAdjusters.firstDayOfMonth());
        // 当月最后一天
        LocalDate end = date.with(TemporalAdjusters.lastDayOfMonth());
        String st = start + " 00:00:00";
        String et = end + " 23:59:59";
        QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
        queryWrapper.between("create_time", st, et);
        StoreSearchParams searchParams = new StoreSearchParams();
        searchParams.setStoreStatus(StoreStatusEnum.OPEN.name());
        searchParams.setScene(SceneEnums.STORE.name());
        List<Store> storeList = storeClient.list(searchParams);
        if (!storeList.isEmpty()) {
            List<String> list = storeList.stream().map(Store::getId).toList();
            queryWrapper.in("store_id", list);
        }
        Page<StoreSaleTopVO> page = this.baseMapper.getStoreSaleRank(PageUtil.initPage(params), queryWrapper);
        if (!page.getRecords().isEmpty()) {
            page.getRecords().forEach(storeSaleTopVO -> {
                StoreVO storeVO = storeClient.getStore(storeSaleTopVO.getStoreId());
                if (null != storeVO && StringUtils.isNotEmpty(storeVO.getUsername())) {
                    storeSaleTopVO.setStoreName(storeVO.getStoreName());
                }
                storeSaleTopVO.setStoreLogo(storeVO.getStoreLogo());
            });
        }
        return page;
    }

    /**
     * 获取当前下级，所有的区域的订单，将订单地址分成组
     *
     * @return 区域分组
     */
    @Override
    public List<RegionalGroupingVO> regionalGrouping() {
        //查找直推下级
        //根据下级获取，下级订单
        LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<Order>().in(Order::getLowerCommissId, UserContext.getCurrentId());
        wrapper.select(Order::getId, Order::getBuyerId, Order::getConsigneeAddressIdPath, Order::getConsigneeAddressPath);
        List<Order> orderList = super.list(wrapper);
        if (CollectionUtil.isEmpty(orderList)) {
            return new ArrayList<>();
        }
        log.info("UserContext.getCurrentId() == {}", UserContext.getCurrentId());
        log.info("orderList == {}", JSONObject.toJSONString(orderList));
        //根据下级订单地址分组。得到有什么些区域
        Map<String, List<Order>> orderMap = orderList.stream().filter(f -> StringUtils.isNotEmpty(f.getConsigneeAddressIdPath())).collect(Collectors.groupingBy(Order::getConsigneeAddressIdPath));
        log.info("orderMap == {}", JSONObject.toJSONString(orderMap));
        //数据转换
        return this.conversionRegionalGrouping(orderMap);
    }

    /**
     * 数据转换
     *
     * @param orderMap 数据
     * @return 目标数据
     */
    private List<RegionalGroupingVO> conversionRegionalGrouping(Map<String, List<Order>> orderMap) {
        if (CollectionUtil.isEmpty(orderMap)) {
            return new ArrayList<>();
        }
        List<RegionalGroupingVO> result = new ArrayList<>();
        for (Map.Entry<String, List<Order>> orderEntry : orderMap.entrySet()) {
            RegionalGroupingVO groupingVO = new RegionalGroupingVO();
            //获取key的最后一个逗号后面的值
            String key = orderEntry.getKey();
            String[] keyParts = key.split(",");
            String lastKeyPart = "";
            if (keyParts.length >= 4) {
                lastKeyPart = keyParts[keyParts.length - 2].trim();
            } else {
                lastKeyPart = keyParts[keyParts.length - 1].trim();
            }

            //获取path的倒数第二个逗号后面的值
            String secondLastPathPart = "";
            List<Order> list = orderEntry.getValue().stream().filter(f -> StringUtils.isNotEmpty(f.getConsigneeAddressPath())).toList();
            if (CollectionUtil.isNotEmpty(list)) {
                String path = list.get(0).getConsigneeAddressPath();
                String[] pathParts = path.split(",");
                if (pathParts.length >= 4) {
                    secondLastPathPart = pathParts[pathParts.length - 3].trim() + "-" + pathParts[pathParts.length - 2].trim();
                } else {
                    secondLastPathPart = pathParts[pathParts.length - 2].trim() + "-" +pathParts[pathParts.length - 1].trim();
                }
            }

            groupingVO.setId(lastKeyPart);
            groupingVO.setName(secondLastPathPart);
            result.add(groupingVO);
        }
        log.info("result ====== {}" , JSONObject.toJSONString(result));

        //将当前用户最近的一次的获取地址排放到最前方
        LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Order::getBuyerId, UserContext.getCurrentId());
        queryWrapper.isNotNull(Order::getConsigneeAddressIdPath);
        queryWrapper.ne(Order::getConsigneeAddressIdPath, "");
        queryWrapper.orderByDesc(Order::getCreateTime);
        queryWrapper.last("limit 1");
        Order order = super.getOne(queryWrapper);
        if (order == null) {
            return result;
        }
        //如果存在将这条记录，过滤掉，然后插入到下标0的位置
        String[] paths = order.getConsigneeAddressIdPath().split(",");
        String lastPath = "";
        if (paths.length >= 4) {
            lastPath = paths[paths.length - 2].trim();
        } else {
            lastPath = paths[paths.length - 1].trim();
        }
        List<RegionalGroupingVO> newResult = new ArrayList<>();
        RegionalGroupingVO groupingVO = null;
        for (RegionalGroupingVO vo : result) {
            if (vo.getId().equals(lastPath)) {
                groupingVO = vo;
            } else {
                newResult.add(vo);
            }
        }
        if (groupingVO != null) {
            newResult.add(0, groupingVO);
        }
        log.info("newResult ====== {}" , JSONObject.toJSONString(newResult));
        return newResult.stream().distinct().collect(Collectors.toList());
    }

    @Override
    public LambdaQueryWrapper<Order> createWrapperDirectPushOrderList(DirectPushOrderParams pushOrderParams) {
        LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper<>();
        //直推用户
//        List<String> buyerIdList = null;
//        Map<String, List<String>> listMap = userClient.selectChildUserIdsByMemberIds(Collections.singletonList(UserContext.getCurrentId()));
//        if (CollectionUtil.isNotEmpty(listMap)) {
//            buyerIdList = listMap.get(UserContext.getCurrentId());
//        }
//        if (CollectionUtil.isEmpty(buyerIdList)) {
//            return queryWrapper.eq(Order::getId, -1);
//        }
//        queryWrapper.in(Order::getBuyerId, buyerIdList);
        //本月
        YearMonth currentMonth = YearMonth.now();
        LocalDate firstDayOfMonth = currentMonth.atDay(1);
        LocalDate lastDayOfMonth = currentMonth.atEndOfMonth();
        queryWrapper.between(Order::getCreateTime, firstDayOfMonth.atStartOfDay(), lastDayOfMonth.atTime(23, 59, 59));

//        if (pushOrderParams.getType() != null) {
//            //1已结算 2待订单完成 3待结算 4用户退单
//            if (OrderConstant.DIRECT_PUSH_ORDER_TYPE_1.equals(pushOrderParams.getType())) {
//                queryWrapper.eq(Order::getOrderStatus, OrderStatusEnum.COMPLETED.name());
//            }
//            if (OrderConstant.DIRECT_PUSH_ORDER_TYPE_2.equals(pushOrderParams.getType())) {
//                queryWrapper.in(Order::getOrderStatus, OrderStatusEnum.UNDELIVERED.name(), OrderStatusEnum.DELIVERED.name());
//            }
//            if (OrderConstant.DIRECT_PUSH_ORDER_TYPE_3.equals(pushOrderParams.getType())) {
//                queryWrapper.eq(Order::getOrderStatus, OrderStatusEnum.COMPLETED.name());
//            }
//            if (OrderConstant.DIRECT_PUSH_ORDER_TYPE_4.equals(pushOrderParams.getType())) {
//                queryWrapper.in(Order::getOrderStatus, OrderStatusEnum.SUBJECT_TO_SALE.name(), OrderStatusEnum.CANCELLED.name());
//            }
//        }
        if (StringUtils.isNotEmpty(pushOrderParams.getRegionId())) {
            queryWrapper.like(Order::getConsigneeAddressIdPath, pushOrderParams.getRegionId());
        }
        queryWrapper.orderByDesc(Order::getCreateTime);
        return queryWrapper;
    }

    /**
     * 所属区域今日首单
     * @param province
     * @param city
     * @return
     */
    @Override
    public OrderVO todayOrderForUnion(String province, String city) {
        LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.ge(Order::getPaymentTime,DateUtil.beginOfDay(new Date()));
        queryWrapper.like(Order::getConsigneeAddressPath,province+","+city+"%");
        queryWrapper.orderByAsc(Order::getId);
        queryWrapper.last("limit 1");
        Order order = this.baseMapper.selectOne(queryWrapper);
        if(null!=order){
            List<OrderItem> orderItemList = orderItemService.getByOrderSn(order.getSn());
            return new OrderVO(order,orderItemList);
        }
        return null;

    }



    /**
     * 所属区域今日首单
     * @param
     * @return
     */
    @Override
    public OrderVO todayOrderForUnion(List<String> buyerIdList) {
        LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.ge(Order::getPaymentTime,DateUtil.beginOfDay(new Date()));
        queryWrapper.in(Order::getLowerCommissId,buyerIdList);
        queryWrapper.orderByAsc(Order::getId);
        queryWrapper.last("limit 1");
        Order order = this.baseMapper.selectOne(queryWrapper);
        if(null!=order){
            List<OrderItem> orderItemList = orderItemService.getByOrderSn(order.getSn());
            return new OrderVO(order,orderItemList);
        }
        return null;

    }



    @Override
    public Page<OrderVO> getOrderByPage (String province, String city, Integer pageSize, Integer pageNo){
        Page<Order> page = new Page<>(pageNo,pageSize);
        List<OrderVO> dataList = new ArrayList<>();
        Date today = new Date();
        Date st = DateUtil.beginOfDay(today);
        Date et = DateUtil.endOfDay(today);
        LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.le(Order::getPaymentTime,et);
        queryWrapper.ge(Order::getPaymentTime,st);
        queryWrapper.like(Order::getConsigneeAddressPath,province+","+city+"%");
        queryWrapper.orderByAsc(Order::getId);
        IPage<Order> orderPage = this.baseMapper.selectPage(page,queryWrapper);
        if(!orderPage.getRecords().isEmpty()){
            orderPage.getRecords().forEach((order)->{
                List<OrderItem> orderItemList = orderItemService.getByOrderSn(order.getSn());
                dataList.add(new OrderVO(order,orderItemList));
            });
        }
        Page<OrderVO> dataPage = new Page<OrderVO>();
        dataPage.setPages(orderPage.getPages());
        dataPage.setRecords(dataList);
        dataPage.setTotal(orderPage.getTotal());
        dataPage.setSize(pageSize);
        dataPage.setCurrent(pageNo);
        return dataPage;


    }






    /**
     * 城主收益列表
     * @param dto
     * @return
     */
    @Override
    public CityDistributionVO getCityDistributionComissList(CityDistributionDTO dto) {
        CityDistributionVO vo = new CityDistributionVO();
        CityDistribution cityDis = cityDistributionClient.getCityDistributionById(dto.getId());
        if (null != cityDis) {
            //处理参数
            this.processParamDto(dto, cityDis);
            log.info("getCityDistributionComissList == {}", JSONObject.toJSONString(dto));
            Page<OrderItemViewVO> voPage = baseMapper.getCityDistributionComissList(new Page(dto.getPageNumber(), dto.getPageSize()), dto);
            if (CollectionUtil.isNotEmpty(voPage.getRecords())) {
                voPage.getRecords().stream().forEach(e -> {
                    if (e.getProfitSharing().equals(ProfitSharingStatusEnum.FINISHED.name())) {
                        e.setProfitSharing("已结算");
                    } else if (e.getProfitSharing().equals(ProfitSharingStatusEnum.PROCESSING.name()) || e.getProfitSharing().equals(ProfitSharingStatusEnum.WAIT_COMPLETE.name())) {
                        e.setProfitSharing("待结算");
                    } else if (e.getProfitSharing().equals(ProfitSharingStatusEnum.ORDER_CANCEL.name()) || e.getProfitSharing().equals(ProfitSharingStatusEnum.AFTER_SALE.name())) {
                        e.setProfitSharing("已退单");
                    }
                });
                vo.setFlowVOPage(voPage);
            } else {
                vo.setFlowVOPage(new Page());
            }
            //统计 已结算、未结算、已退单、合计金额
            this.getCityDistributionSumComiss(dto,vo);
            //发放状态
            vo.setComissStatusName(ComissStatusEnum.getByCode(cityDis.getComissStatus()));
            //拼接title
            vo.setTitle(cityDis.getPrivinceName() + cityDis.getCityName() + cityDis.getDistrictName() + "城主收益/" + cityDis.getYearDate() + "-" + String.format("%02d", cityDis.getMonthDate()));
        }
        return vo;
    }

    //统计 已结算、未结算、已退单、合计金额
    private void getCityDistributionSumComiss(CityDistributionDTO dto, CityDistributionVO vo) {
        Map<String,BigDecimal> sumVoMap = baseMapper.getCityDistributionSumComiss(dto);
        if (CollectionUtil.isNotEmpty(sumVoMap)) {
            vo.setSettledPrice(sumVoMap.get("settledPrice").doubleValue());
            vo.setUnsettledPrice(sumVoMap.get("unsettledPrice").doubleValue());
            vo.setReturnPrice(sumVoMap.get("returnPrice").doubleValue());
            vo.setTotalPrice(vo.getSettledPrice() + vo.getUnsettledPrice() + vo.getReturnPrice());
        }
    }

    /**
     * 处理参数
     * @param dto
     * @param cityDis
     */
    private void processParamDto(CityDistributionDTO dto,CityDistribution cityDis){
        //根据区域查订单
        if (dto.getYearDate() != null && dto.getMonthDate() != null) {
            dto.setStartLocalDate(LocalDate.of(dto.getYearDate(), dto.getMonthDate(), 01).toString());
            //结束日期
            dto.setEndLocalDate(LocalDate.of(dto.getYearDate(), dto.getMonthDate(), 01).plusMonths(1).toString());
        } else {
            dto.setStartLocalDate(LocalDate.now().withDayOfMonth(1).toString());
            dto.setEndLocalDate(LocalDate.now().withDayOfMonth(1).plusMonths(1).toString());
        }
        dto.setJoinAddressCode(cityDis.getPrivinceCode() + "," + cityDis.getCityCode() + "," + cityDis.getDistrictCode());
        if (dto.getProfitSharingType() != null && dto.getProfitSharingType() == 1) {
            //已结算
            dto.setProfitSharing(ProfitSharingStatusEnum.FINISHED.name());
        } else if (dto.getProfitSharingType() != null && dto.getProfitSharingType() == 2) {
            //待结算
            dto.setProfitSharing("'" + ProfitSharingStatusEnum.PROCESSING.name() + "','" + ProfitSharingStatusEnum.WAIT_COMPLETE.name() + "'");
        } else if (dto.getProfitSharingType() != null && dto.getProfitSharingType() == 3) {
            //退单
            dto.setProfitSharing("'" + ProfitSharingStatusEnum.ORDER_CANCEL.name() + "','" + ProfitSharingStatusEnum.AFTER_SALE.name() + "'");
        }
    }

    /**
     * 是否存在未完成的订单
     * @param joinAddress
     * @param startLocalDate
     * @param endLocalDate
     * @return
     */
    @Override
    public Boolean isExistsUnCompletedOrder(String joinAddress, LocalDate startLocalDate, LocalDate endLocalDate) {
//        LambdaQueryWrapper<Order> query = new LambdaQueryWrapper<>();
//        List<String> orderStatusList = new ArrayList<>();
//        orderStatusList.add(OrderStatusEnum.PAID.name());
//        orderStatusList.add(OrderStatusEnum.PLATFORM_PAID.name());
//        orderStatusList.add(OrderStatusEnum.UNDELIVERED.name());
//        orderStatusList.add(OrderStatusEnum.DELIVERED.name());
//        orderStatusList.add(OrderStatusEnum.OVERVIEW.name());
//        orderStatusList.add(OrderStatusEnum.STAY_PICKED_UP.name());
//        orderStatusList.add(OrderStatusEnum.SUBJECT_TO_SALE.name());
//        orderStatusList.add(OrderStatusEnum.TAKE.name());
//        query.in(true, Order::getOrderStatus, orderStatusList);
//        query.likeRight(Order::getConsigneeAddressIdPath, joinAddress);
//        query.ge(true, Order::getCreateTime, startLocalDate);
//        query.lt(true, Order::getCreateTime, endLocalDate);
//        return baseMapper.selectCount(query) > 0;
        return baseMapper.isExistsUnCompletedOrder(joinAddress,startLocalDate,endLocalDate) > 0;
    }

    @Override
    public Boolean isExistsUnCompletedOrderByOc(String joinAddress, LocalDate startLocalDate, LocalDate endLocalDate) {
        return baseMapper.isExistsUnCompletedOrderByOc(joinAddress,startLocalDate,endLocalDate) > 0;
    }

    /**
     * 定时任务城主发放佣金、发放查询订单
     * @param joinAddress
     * @param startLocalDate
     * @param endLocalDate
     * @return
     */
    @Override
    public List<OrderItemViewVO> getCityDistributionSumComissByTaskTime(Integer pageNum, Integer pageSize, String joinAddress, LocalDate startLocalDate, LocalDate endLocalDate) {
        return baseMapper.getCityDistributionSumComissByTaskTime(new Page(pageNum, pageSize, false), joinAddress, startLocalDate, endLocalDate);
    }

    @Override
    public List<OrderItemViewVO> getUnionSumComissByTaskTime(Integer pageNum, Integer pageSize, String joinAddress, LocalDate startLocalDate, LocalDate endLocalDate) {
        return baseMapper.getUnionSumComissByTaskTime(new Page(pageNum, pageSize, false), joinAddress, startLocalDate, endLocalDate);
    }

    /**
     * 返回上个月，有哪些区域订单
     * @param begin 上个与开始时间
     * @param end 上个月结束时间
     * @return 有哪些区域订单
     */
    @Override
    public List<String> executeCityDistributionLastMonthOrder(LocalDateTime begin, LocalDateTime end, Integer subDistributionCount) {
        return baseMapper.executeCityDistributionLastMonthOrder(begin, end, subDistributionCount);
    }

    @Override
    public Page<OrderVO> getOrderByPage(List<String> buyerIdList, Integer pageNo, Integer pageSize) {
        Page<Order> page = new Page<>(pageNo,pageSize);
        List<OrderVO> dataList = new ArrayList<>();
        Date today = new Date();
        Date st = DateUtil.beginOfDay(today);
        Date et = DateUtil.endOfDay(today);
        LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.le(Order::getPaymentTime,et);
        queryWrapper.ge(Order::getPaymentTime,st);
        queryWrapper.in(Order::getLowerCommissId,buyerIdList);
        queryWrapper.orderByDesc(Order::getId);
        IPage<Order> orderPage = this.baseMapper.selectPage(page,queryWrapper);
        if(!orderPage.getRecords().isEmpty()){
            orderPage.getRecords().forEach((order)->{
                List<OrderItem> orderItemList = orderItemService.getByOrderSn(order.getSn());
                dataList.add(new OrderVO(order,orderItemList));
            });
        }
        Page<OrderVO> dataPage = new Page<OrderVO>();
        dataPage.setPages(orderPage.getPages());
        dataPage.setRecords(dataList);
        dataPage.setTotal(orderPage.getTotal());
        dataPage.setSize(pageSize);
        dataPage.setCurrent(pageNo);
        return dataPage;
    }

    /**
     * 根据区域查询所有月份
     * @param
     * @return
     */
    @Override
    public Page<UnionMonthFundsVO> getOrderMonth (UnionOrderParams params) {
        return baseMapper.getOrderMonthByRegion(PageUtil.initPage(params), params.getRegionId());
    }

    /**
     * 根据区域查询所有订单
     * @param regionId
     * @return
     */
    @Override
    public List<String> getOrderSnByMonth (String regionId, String month) {
        return baseMapper.getOrderSnByMonth(regionId, month);
    }

    /**
     * 推送订单给第三方平台
     * @return
     */
    @Override
    public ResultMessage<Object> pushOrderToThirdGrabOrder(String orderNos) {
        Map<String, Object> resultMap = new HashMap<>(21);
        String[] ordernoArray = orderNos.split(",");
        for (String orderNo : ordernoArray) {
            GrabOrderParam param = this.getOrderItemsByOrderSn(orderNo);
            if (null == param) {
                resultMap.put("订单号:" + orderNo, "param=null");
                log.info("#pushOrderToThirdGrabOrder# 订单号:{}", orderNo + " param=null");
                continue;
            }
            log.info("#pushOrderToThirdGrabOrder# 订单号:" + orderNo, "orderItemList个数:" + param.getOrderItems().size());
            resultMap.put("订单号:" + orderNo, "orderItemList个数:" + param.getOrderItems().size());
            grabOrderClient.grabOrder(param);
        }
        return ResultUtil.data(resultMap);
    }

    public GrabOrderParam getOrderItemsByOrderSn(String orderNos) {
        LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(true, Order::getSn, orderNos);
        queryWrapper.last("limit 1");
        Order order = baseMapper.selectOne(queryWrapper);
        if (null != order) {
            List<OrderItem> orderItems = orderItemService.getByOrderSn(order.getSn());
            if (CollUtil.isNotEmpty(orderItems)) {
                //第三方-采集下单（企叮当）
                GrabOrderParam grabOrderParam = new GrabOrderParam();
                grabOrderParam.setOrder(order);
                grabOrderParam.setOrderItems(orderItems);
                return grabOrderParam;
            }
        }
        return null;
    }


    /**
     * 手动处理支付未成功订单补偿
     * @param orderParam
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultMessage<Object> handlePayNotSuccessOrder(Order orderParam) {
        if (StrUtil.isBlank(orderParam.getSn())) {
            return ResultUtil.error(400, "sn单号不可为空");
        }
        LambdaQueryWrapper<Order> query = new LambdaQueryWrapper<>();
        query.eq(true, Order::getSn, orderParam.getSn());
        Order order = super.getOne(query);
        if (ObjectUtil.isNull(order)) {
            return ResultUtil.error(400, "未找到该未付款的订单");
        }
        if (!order.getOrderStatus().equals(OrderStatusEnum.UNPAID.name()) && !order.getOrderStatus().equals(OrderStatusEnum.CANCELLED.name())) {
            return ResultUtil.error(400, "该订单可能是已付款状态,请确认该订单是否存在异常");
        }
        //查询该订单是否为售后取消的订单
        LambdaQueryWrapper<AfterSale> afterSale = new LambdaQueryWrapper<>();
        afterSale.eq(true, AfterSale::getServiceStatus, AfterSaleStatusEnum.COMPLETE.name());
        afterSale.eq(true, AfterSale::getOrderSn, orderParam.getSn());
        long afterSalesCount = afterSaleService.count(afterSale);
        if (afterSalesCount > 0) {
            return ResultUtil.error(400, "该订单为售后取消,不是支付异常订单");
        }

        PaymentLog paymentLog = paymentClient.getPaymentLogByOrderSN(order.getSn());
        if (ObjectUtil.isNull(paymentLog)) {
            return ResultUtil.error(400, "未找到该订单已支付的支付日志");
        }

        LambdaQueryWrapper<Trade> queryTrade = new LambdaQueryWrapper<>();
        queryTrade.eq(true, Trade::getSn, order.getTradeSn());
        Trade trade = tradeService.getOne(queryTrade);
        if (ObjectUtil.isNull(trade)) {
            return ResultUtil.error(400, "未找到该订单的Trade数据");
        }

        //查找trade和paymentLog,新增order_flow表
        LambdaQueryWrapper<OrderFlow> queryOrderFlow = new LambdaQueryWrapper<>();
        queryOrderFlow.eq(true, OrderFlow::getOrderSn, order.getTradeSn());
        long count = orderFlowService.count(queryOrderFlow);
        if (count <= 0) {
            //1,更新order , trade
            order.setOrderStatus(OrderStatusEnum.UNDELIVERED.name());
            order.setPaymentMethod(paymentLog.getPaymentMethod());
            order.setPaymentTime(paymentLog.getCreateTime());
            order.setPayStatus(OrderStatusEnum.PAID.name());
            order.setOutTradeNo(paymentLog.getOutTradeNo());
            order.setTransactionId(paymentLog.getTransactionId());
            int result = baseMapper.updateById(order);
            trade.setPaymentMethod(paymentLog.getPaymentMethod());
            trade.setOrderStatus(OrderStatusEnum.PAID.name());
            boolean flagResult = tradeService.updateById(trade);
            if (result > 0 && flagResult) {
                //2,新增orderFlow数据逻辑
                List<OrderItem> orderItems = orderItemService.getByOrderSn(order.getSn());
                orderFlowService.payOrder(order, orderItems);
                return ResultUtil.success();
            } else {
                throw new ServiceException("处理订单失败,稍后再试");
            }
        } else {
            return ResultUtil.error(400, "OrderFlow存在数据,请检查订单数据异常");
        }
    }

    /**
     * 获取运营中心的省份id --》  获取所属省份的订单 --》 订单数量统计
     * 首页订单数量统计
     */
    @Override
    public ResultMessage<HomeResult> orderQuantityStatistics() {
        HomeResult homeResult = HomeResultUtil.createDefaultValue();
        AuthUser authUser = UserContext.getCurrentUser();
        if (authUser == null) {
            throw new ServiceException("用户信息为空");
        }
        //获取运营中心的省份id
        OperationCenter operationCenter = operationCenterClient.getOperationCenter(authUser.getId());
        if (operationCenter == null) {
            throw new ServiceException("未获取到，运营中心信息");
        }
        //获取所属省份的订单
        /*LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.apply("FIND_IN_SET('" + operationCenter.getProvinceId() + "', consignee_address_id_path)");
        queryWrapper.select(Order::getId, Order::getCreateTime);
        List<Order> orderList = super.list(queryWrapper);
        if (CollectionUtil.isEmpty(orderList)) {
            return ResultUtil.data(homeResult);
        }
        //订单数量统计
        homeResult = HomeResultUtil.createResult(orderList, order -> {
            Date createTime = order.getCreateTime();
            return createTime.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        });*/

        return this.operationCenterOrderStatistics();
    }


    /**
     * 收货地址为运营中心本省的分销订单列表
     * @param vo
     * @return
     */
    @Override
    public Page<OrderViewVO> getOperationCenterOrderList(OrderViewVO vo) {
        Page<OrderViewVO> page = null;
        AuthUser currentUser = Objects.requireNonNull(UserContext.getCurrentUser());
        if (currentUser == null) {
            return new Page<>();
        }
        //查询当前登陆用户是哪个运营中心的用户
        LambdaQueryWrapper<OperationCenter> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(true, OperationCenter::getUserId, currentUser.getId());
        OperationCenter operationCenter = operationCenterClient.getOperationCenter(currentUser.getId());
        if (operationCenter == null || StrUtil.isEmpty(operationCenter.getProvinceId())) {
            throw new ServiceException("未获取到，运营中心信息");
        }
        vo.setJoinAddress(operationCenter.getProvinceId());
        if (StringUtils.isNotEmpty(vo.getProfitSharing())) {
            List<String> list = new ArrayList<>();
            if (vo.getProfitSharing().equals(ProfitSharingStatusEnum.AFTER_SALE.name())) {
                list.add(ProfitSharingStatusEnum.ORDER_CANCEL.name());
                list.add(ProfitSharingStatusEnum.AFTER_SALE.name());
            }else if (vo.getProfitSharing().equals(ProfitSharingStatusEnum.WAIT_COMPLETE.name())) {
                list.add(ProfitSharingStatusEnum.WAIT_COMPLETE.name());
                list.add(ProfitSharingStatusEnum.PROCESSING.name());
            }else if (vo.getProfitSharing().equals(ProfitSharingStatusEnum.FINISHED.name())){
                list.add(ProfitSharingStatusEnum.FINISHED.name());
            }
            vo.setProfitSharingList(list);
        }
        //获取所属省份的订单
        page = baseMapper.getOperationCenterOrderList(new Page<>(vo.getPageNumber(), vo.getPageSize()), vo);
        /*if (!page.getRecords().isEmpty()) {
            page.getRecords().forEach(order -> {
                if (StringUtils.isNotEmpty(order.getBuyerId())) {
                    User user = userClient.getById(order.getBuyerId());
                    order.setNickname(user.getFyName());
                }
                if (StringUtils.isNotEmpty(order.getDistributionId())) {
                    User user = userClient.getById(order.getDistributionId());
                    order.setDistributionName(user.getFyName());
                }
            });
        }*/
        return page;
    }


    /**
     * 订单数量统计
     * @return
     */
    @Override
    public ResultMessage<HomeResult> operationCenterOrderStatistics() {
        HomeResult homeResult = new HomeResult();
        OrderViewVO vo = new OrderViewVO();
        // 1,总订单数 单独统计
        // 2,本月，本周，今日 调用用上面的方法，并传参 当月 开始时间和结束时间
        Page<OrderViewVO> vos = null;
        AuthUser currentUser = Objects.requireNonNull(UserContext.getCurrentUser());
        if (currentUser == null) {
            return ResultUtil.error(400, "未登陆");
        }
        //查询当前登陆用户是哪个运营中心的用户
        LambdaQueryWrapper<OperationCenter> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(true, OperationCenter::getUserId, currentUser.getId());
        OperationCenter operationCenter = operationCenterClient.getOperationCenter(currentUser.getId());
        if (operationCenter == null || StrUtil.isEmpty(operationCenter.getProvinceId())) {
            throw new ServiceException("未获取到，运营中心信息");
        }
        vo.setJoinAddress(operationCenter.getProvinceId());

        /*LocalDate currentDate = LocalDate.now();
        // 获取当月的第一天的最小时间
        LocalDateTime startOfMonth = LocalDateTime.of(currentDate.withDayOfMonth(1), LocalTime.MIN);
        // 获取当月的最后一天的最大时间
        LocalDateTime endOfMonth = LocalDateTime.of(currentDate.withDayOfMonth(currentDate.lengthOfMonth()), LocalTime.MAX);
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

        vo.setStartTime(startOfMonth.format(formatter));
        vo.setEndTime(endOfMonth.format(formatter));*/
        //获取所属省份的订单
        vos = baseMapper.getOperationCenterOrderList(new Page<>(vo.getPageNumber(), 99999), vo);
        if (CollUtil.isNotEmpty(vos.getRecords())) {
            //订单数量统计
            homeResult = HomeResultUtil.createResult(vos.getRecords(), order -> {
                Date createTime = order.getCreateTime();
                return createTime.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
            });
        }
        //Integer count = baseMapper.operationCenterOrderStatistics(vo);
        //单独统计数量
        homeResult.setCount(vos.getTotal());
        return ResultUtil.data(homeResult);
    }

    /**
     * 数据统计  ==> 订单数量统计/订单金额/订单成本
     */
    @Override
    public DataStatisticsResult dataStatistics(String scene, String startDate, String endDate, Boolean isNeedProcessDate) {
        //查询order / orderItem / orderFlow表，  根据时间范围查询。如果没有传查询当前月份
        String storeId = null;
        if (scene.equals(SceneEnums.STORE.name())) {
            storeId = UserContext.getCurrentUser().getExtendId();
        }

        LambdaQueryWrapper<Order> orderLambdaQueryWrapper = new LambdaQueryWrapper<>();
        orderLambdaQueryWrapper.eq(StrUtil.isNotEmpty(storeId),Order::getStoreId,storeId);
        orderLambdaQueryWrapper.select(Order::getId, Order::getSn, Order::getOrderStatus);
        orderLambdaQueryWrapper.le(Order::getCreateTime, ((isNeedProcessDate) ? endDate : ToolsUtil.processLocalDateTimeParam(endDate, false)));
        orderLambdaQueryWrapper.ge(Order::getCreateTime, ((isNeedProcessDate) ? startDate : ToolsUtil.processLocalDateTimeParam(startDate, true)));
        List<Order> orderList = super.list(orderLambdaQueryWrapper);
        List<String> orderSnList = orderList.stream().map(Order::getSn).collect(Collectors.toList());


        LambdaQueryWrapper<OrderItem> orderItemLambdaQueryWrapper = new LambdaQueryWrapper<>();
        LambdaQueryWrapper<OrderFlow> orderFlowLambdaQueryWrapper = new LambdaQueryWrapper<>();
        orderItemLambdaQueryWrapper.in(CollUtil.isNotEmpty(orderSnList),OrderItem::getOrderSn,orderSnList);
        orderItemLambdaQueryWrapper.select(OrderItem::getSn, OrderItem::getOrderSn, OrderItem::getFlowPrice, OrderItem::getNum, OrderItem::getCostPrice, OrderItem::getAfterSaleStatus);
        orderItemLambdaQueryWrapper.le(OrderItem::getCreateTime, ((isNeedProcessDate) ? endDate : ToolsUtil.processLocalDateTimeParam(endDate, false)));
        orderItemLambdaQueryWrapper.ge(OrderItem::getCreateTime, ((isNeedProcessDate) ? startDate : ToolsUtil.processLocalDateTimeParam(startDate, true)));


        orderFlowLambdaQueryWrapper.select(OrderFlow::getId, OrderFlow::getSn, OrderFlow::getOrderSn, OrderFlow::getProfitSharing, OrderFlow::getLowerCommiss);

        orderFlowLambdaQueryWrapper.in(CollUtil.isNotEmpty(orderSnList), OrderFlow::getOrderSn, orderSnList);
        orderFlowLambdaQueryWrapper.le(OrderFlow::getCreateTime, ((isNeedProcessDate) ? endDate : ToolsUtil.processLocalDateTimeParam(endDate, false)));
        orderFlowLambdaQueryWrapper.ge(OrderFlow::getCreateTime, ((isNeedProcessDate) ? startDate : ToolsUtil.processLocalDateTimeParam(startDate, true)));

        List<OrderItem> orderItemList = orderItemService.list(orderItemLambdaQueryWrapper);

        List<OrderFlow> orderFlowList = orderFlowService.list(orderFlowLambdaQueryWrapper);

        //查询售后记录
        List<AfterSale> afterSaleList = null;
        if (CollUtil.isNotEmpty(orderSnList)) {
            LambdaQueryWrapper<AfterSale> afterSaleLambdaQueryWrapper = new LambdaQueryWrapper<>();
            afterSaleLambdaQueryWrapper.select(AfterSale::getOrderSn, AfterSale::getOrderItemSn, AfterSale::getServiceStatus, AfterSale::getActualRefundPrice, AfterSale::getApplyRefundPrice);
            //订单号
            afterSaleLambdaQueryWrapper.in(true, AfterSale::getOrderSn, orderSnList);
            //售后状态
            afterSaleLambdaQueryWrapper.in(true, AfterSale::getServiceStatus,
                    AfterSaleStatusEnum.APPLY.name(),
                    AfterSaleStatusEnum.PASS.name(),
                    AfterSaleStatusEnum.BUYER_RETURN.name(),
                    AfterSaleStatusEnum.SELLER_CONFIRM.name(),
                    AfterSaleStatusEnum.WAIT_REFUND.name(),
                    AfterSaleStatusEnum.COMPLETE.name()
            );
            afterSaleLambdaQueryWrapper.le(AfterSale::getCreateTime, ((isNeedProcessDate) ? endDate : ToolsUtil.processLocalDateTimeParam(endDate, false)));
            afterSaleLambdaQueryWrapper.ge(AfterSale::getCreateTime, ((isNeedProcessDate) ? startDate : ToolsUtil.processLocalDateTimeParam(startDate, true)));
            afterSaleList = afterSaleService.list(afterSaleLambdaQueryWrapper);
        }


        if (CollectionUtil.isEmpty(orderItemList) || CollectionUtil.isEmpty(orderList) || CollectionUtil.isEmpty(orderFlowList)) {
            log.info("orderItemList = {} \n, orderList = {} \n , orderFlowList = {}\n", JSONObject.toJSONString(orderItemList), JSONObject.toJSONString(orderList), JSONObject.toJSONString(orderFlowList));
            return new DataStatisticsResult();
        }
        DataStatisticsResult result = new DataStatisticsResult();
        //订单统计
        DataStatisticsVO orderStatisticsVO = new DataStatisticsVO();
        //订单金额统计
        DataStatisticsVO orderAmountVO = new DataStatisticsVO();
        //订单成本统计
        DataStatisticsVO orderCostVO = new DataStatisticsVO();
        //有效订单统计
        DataStatisticsTableVO validDataStatistics = new DataStatisticsTableVO();
        //无效订单统计
        DataStatisticsTableVO invalidDataStatistics = new DataStatisticsTableVO();

        //订单统计
        orderStatisticsVO.setToBePaid(this.getOrderCount(orderItemList, orderList, OrderStatusEnum.UNPAID.name(),null));
        //已取消
        orderStatisticsVO.setCancelled(this.getOrderCount(orderItemList, orderList, OrderStatusEnum.CANCELLED.name(),afterSaleList));
        //待发货
        orderStatisticsVO.setFreightForwarding(this.getOrderCount(orderItemList, orderList, OrderStatusEnum.UNDELIVERED.name(),null));
        //已收货
        orderStatisticsVO.setDelivered(this.getOrderCount(orderItemList, orderList, OrderStatusEnum.DELIVERED.name(), null));
        orderStatisticsVO.setCompleted(this.getOrderCount(orderItemList, orderList, OrderStatusEnum.COMPLETED.name(),null));
        orderStatisticsVO.setAfterSale(this.getOrderCount(orderItemList, orderList, AfterSaleStatusEnum.APPLY.name(), afterSaleList));
        orderStatisticsVO.setTotal(this.getTotal(orderStatisticsVO));

        //订单金额统计
        //待支付
        orderAmountVO.setToBePaid(this.getOrderAmount(false, null, orderItemList, orderList, OrderStatusEnum.UNPAID.name(), orderFlowList, false, null));
        orderAmountVO.setCancelled(this.getOrderAmount(false, null, orderItemList, orderList, OrderStatusEnum.CANCELLED.name(), orderFlowList, false, null));
        orderAmountVO.setFreightForwarding(this.getOrderAmount(false, null, orderItemList, orderList, OrderStatusEnum.UNDELIVERED.name(), orderFlowList, false, null));
        orderAmountVO.setDelivered(this.getOrderAmount(false, null, orderItemList, orderList, OrderStatusEnum.DELIVERED.name(), orderFlowList, false, null));
        orderAmountVO.setCompleted(this.getOrderAmount(false, false, orderItemList, orderList, OrderStatusEnum.COMPLETED.name(), orderFlowList, false, afterSaleList));
        //售后订单
        orderAmountVO.setAfterSale(this.getOrderAmount(false, true, orderItemList, orderList, OrderStatusEnum.COMPLETED.name(), orderFlowList, false, afterSaleList));
        //售后退款金额
        orderAmountVO.setReturnAfterSale(this.getOrderAmount(false, true, orderItemList, orderList, OrderStatusEnum.COMPLETED.name(), orderFlowList, true, afterSaleList));
        orderAmountVO.setTotal(this.getTotal(orderAmountVO));

        //订单成本统计
        orderCostVO.setToBePaid(this.getOrderAmount(true, null, orderItemList, orderList, OrderStatusEnum.UNPAID.name(), orderFlowList, false, null));
        orderCostVO.setCancelled(this.getOrderAmount(true, null, orderItemList, orderList, OrderStatusEnum.CANCELLED.name(), orderFlowList, false, afterSaleList));
        orderCostVO.setFreightForwarding(this.getOrderAmount(true, null, orderItemList, orderList, OrderStatusEnum.UNDELIVERED.name(), orderFlowList, false, null));
        orderCostVO.setDelivered(this.getOrderAmount(true, null, orderItemList, orderList, OrderStatusEnum.DELIVERED.name(), orderFlowList, false, null));
        orderCostVO.setCompleted(this.getOrderAmount(true, false, orderItemList, orderList, OrderStatusEnum.COMPLETED.name(), orderFlowList, false, afterSaleList));
        orderCostVO.setAfterSale(this.getOrderAmount(true, true, orderItemList, orderList, OrderStatusEnum.COMPLETED.name(), orderFlowList, false, afterSaleList));
        orderCostVO.setTotal(this.getTotal(orderCostVO));

        //有效订单统计
        validDataStatistics.setCount(orderStatisticsVO.getFreightForwarding().add(orderStatisticsVO.getCompleted().add(orderStatisticsVO.getDelivered())));
        validDataStatistics.setOrderAmount(orderAmountVO.getFreightForwarding().add(orderAmountVO.getCompleted()).add(orderAmountVO.getDelivered()));
        validDataStatistics.setOrderCost(orderCostVO.getFreightForwarding().add(orderCostVO.getCompleted()).add(orderCostVO.getDelivered()));
        validDataStatistics.setApportionment(this.getApport(ProfitSharingStatusEnum.PROCESSING.name(), orderFlowList));
        validDataStatistics.setApportion(this.getApport(ProfitSharingStatusEnum.FINISHED.name(), orderFlowList));
        //订单金额-成本-分佣=净利润
        validDataStatistics.setNetProfit(validDataStatistics.getOrderAmount().subtract(validDataStatistics.getOrderCost()).subtract(validDataStatistics.getApportion()));

        //无效订单统计
        invalidDataStatistics.setCount(orderStatisticsVO.getToBePaid().add(orderStatisticsVO.getCancelled()).add(orderStatisticsVO.getAfterSale()));
        invalidDataStatistics.setOrderAmount(orderAmountVO.getToBePaid().add(orderAmountVO.getCancelled()).add(orderAmountVO.getAfterSale()));
        //退款金额
//      invalidDataStatistics.setOrderRefunded(orderAmountVO.getCancelled().add(orderAmountVO.getAfterSale()));
        invalidDataStatistics.setOrderRefunded(orderAmountVO.getReturnAfterSale());
        //售后订单金额-已退款金额=净利润
        invalidDataStatistics.setNetProfit(orderAmountVO.getAfterSale().subtract(orderAmountVO.getReturnAfterSale()));

        result.setOrderStatistics(orderStatisticsVO);
        result.setOrderAmount(orderAmountVO);
        result.setOrderCost(orderCostVO);
        result.setValidDataStatistics(validDataStatistics);
        result.setInvalidDataStatistics(invalidDataStatistics);
        return result;
    }

    /**
     * 获取总计数据
     * @param vo 订单统计数据
     * @return 总计数据
     */
    private BigDecimal getTotal(DataStatisticsVO vo) {
        return vo.getToBePaid().add(vo.getCancelled()).add(vo.getFreightForwarding()).add(vo.getCompleted()).add(vo.getAfterSale().add(vo.getDelivered()));
    }

    /**
     * 获取分佣金额数据
     *
     * @param profitSharing 分佣状态
     * @param orderFlowList 分佣列表
     * @return 分佣金额数据
     */
    private BigDecimal getApport(String profitSharing, List<OrderFlow> orderFlowList) {
//        double sum = orderFlowList.stream().filter(orderFlow -> profitSharing.equals(orderFlow.getProfitSharing())).mapToDouble(OrderFlow::getLowerCommiss).sum();
        double sum = orderFlowList.stream().filter(e -> profitSharing.equals(ProfitSharingStatusEnum.PROCESSING.name()) &&
                        (e.getProfitSharing().equals(ProfitSharingStatusEnum.WAIT_COMPLETE.name()) ||
                                e.getProfitSharing().equals(ProfitSharingStatusEnum.PROCESSING.name()) ||
                                e.getProfitSharing().equals(ProfitSharingStatusEnum.FAIL.name())) ||
                        profitSharing.equals(e.getProfitSharing()))
                .mapToDouble(OrderFlow::getLowerCommiss) // 将符合条件的元素映射为 double 类型
                .sum(); // 对映射后的 double 类型元素进行累加
        return BigDecimal.valueOf(sum);
    }


    /**
     * 返回每个状态对应的数量， 已完成状态需要区分是否售后
     *
     * @param orderItemList 订单子列表
     * @param orderList 订单列表
     * @param status 状态
     * @return 数量
     */
    public BigDecimal getOrderCount(List<OrderItem> orderItemList, List<Order> orderList, String status, List<AfterSale> afterSaleList) {
        AtomicInteger atomic = new AtomicInteger(0);
        Map<String, String> hash = new HashMap<>(256);
        //已完成  ||  已售后(已售后的订单状态也会是已完成)
        boolean completed = OrderStatusEnum.COMPLETED.name().equals(status);
        boolean apply = AfterSaleStatusEnum.APPLY.name().equals(status);
        //售后订单
        Map<String, List<AfterSale>> afterSaleMap = CollUtil.isNotEmpty(afterSaleList) ? afterSaleList.stream().collect(Collectors.groupingBy(AfterSale::getOrderSn)) : null;
        if (completed || apply) {
            Map<String, List<OrderItem>> orderItemMap = orderItemList.stream().collect(Collectors.groupingBy(OrderItem::getOrderSn));
            orderItemList.parallelStream().forEach(orderItem -> {
                //已添加过数量的不重复计算
                if (hash.get(orderItem.getOrderSn()) != null) {
                    return;
                }
                for (Order order : orderList) {
                    if (order.getSn().equals(orderItem.getOrderSn()) && OrderStatusEnum.COMPLETED.name().equals(order.getOrderStatus())) {
                        List<OrderItem> orderItemMapList = orderItemMap.get(orderItem.getOrderSn());
                        //是否申请过售后
                        boolean isAfterSale = false;
                        for (OrderItem item : orderItemMapList) {
                            //申请售后
                            boolean alreadyApplied = OrderItemAfterSaleStatusEnum.ALREADY_APPLIED.name().equals(item.getAfterSaleStatus());
                            //部分售后
                            boolean afterSale = OrderItemAfterSaleStatusEnum.PART_AFTER_SALE.name().equals(item.getAfterSaleStatus());
                            if (alreadyApplied || afterSale) {
                                isAfterSale = true;
                                break;
                            }
                        }
                        //已完成,且没有进行过售后的订单数量
                        if (completed && !isAfterSale && (CollUtil.isEmpty(afterSaleMap) || afterSaleMap.get(order.getSn()) == null)) {
                            atomic.incrementAndGet();
                            hash.put(orderItem.getOrderSn(), orderItem.getOrderSn());
                        }else
                        //已完成,已完成但售后过的订单数量
                        if (apply && isAfterSale) {
                            atomic.incrementAndGet();
                            hash.put(orderItem.getOrderSn(), orderItem.getOrderSn());
                        } else {
                            //售后订单
                            if (CollUtil.isNotEmpty(afterSaleMap) && afterSaleMap.get(order.getSn()) != null) {
                                atomic.incrementAndGet();
                            }
                        }
                    }
                }
            });
        } else {
            //直接统计数量
            orderList.parallelStream().forEach(order -> {
                if (order.getOrderStatus().equals(status) && !OrderStatusEnum.CANCELLED.name().equals(order.getOrderStatus())) {
                    atomic.incrementAndGet();
                } else if (order.getOrderStatus().equals(status) && OrderStatusEnum.CANCELLED.name().equals(status)) {
                    //取消的订单统计,排除售后取消的订单
                    if (CollUtil.isEmpty(afterSaleMap) || afterSaleMap.get(order.getSn()) == null) {
                        atomic.incrementAndGet();
                    }
                }
            });
        }
        return BigDecimal.valueOf(atomic.get());
    }

    /**
     * 返回每个状态对应的订单金额， 已完成状态需要区分是否售后
     *
     * @param isCost        是成本价 / 是售卖价
     * @param isAfterSale   null 普通状态订单，  true售后订单    false已完成订单
     * @param orderItemList 订单子列表
     * @param orderList     订单列表
     * @param status        状态
     * @param orderFlowList 订单流水
     * @param returnAfter   售后退款金额  /  售后流水金额
     * @return 订单金额
     */
    public BigDecimal getOrderAmount(Boolean isCost, Boolean isAfterSale, List<OrderItem> orderItemList, List<Order> orderList, String status, List<OrderFlow> orderFlowList, Boolean returnAfter, List<AfterSale> afterSaleList) {
        BigDecimal totalAmount = BigDecimal.ZERO;
        //售后中的订单
        Map<String, List<AfterSale>> afterSaleingMap = CollUtil.isNotEmpty(afterSaleList) ? afterSaleList.stream().filter(afterSale -> !afterSale.getServiceStatus().equals(AfterSaleStatusEnum.COMPLETE.name())).collect(Collectors.groupingBy(AfterSale::getOrderItemSn)) : null;
        //售后退款订单
        Map<String, List<AfterSale>> afterSaleFinishMap = CollUtil.isNotEmpty(afterSaleList) ? afterSaleList.stream().filter(afterSale -> afterSale.getServiceStatus().equals(AfterSaleStatusEnum.COMPLETE.name()) && afterSale.getActualRefundPrice() != null && afterSale.getActualRefundPrice() > 0.0).collect(Collectors.groupingBy(AfterSale::getOrderItemSn)) : null;
        for (Order order : orderList) {
            if (status.equals(order.getOrderStatus())) {
                List<OrderItem> items = orderItemList.stream()
                        .filter(item -> item.getOrderSn().equals(order.getSn()))
                        .toList();
                for (OrderItem item : items) {
                    //普通订单金额计算
                    if (isAfterSale == null) {
                        //-------------------------------------成本x数量
                        totalAmount = totalAmount.add(isCost ? (item.getCostPrice() != null ? BigDecimal.valueOf(item.getCostPrice()).multiply(new BigDecimal(item.getNum())) : BigDecimal.ZERO) : (item.getFlowPrice() != null ? BigDecimal.valueOf(item.getFlowPrice()) : BigDecimal.ZERO));
                    } else {
                        //申请售后
                        boolean alreadyApplied = OrderItemAfterSaleStatusEnum.ALREADY_APPLIED.name().equals(item.getAfterSaleStatus());
                        //部分售后
                        boolean afterSale = OrderItemAfterSaleStatusEnum.PART_AFTER_SALE.name().equals(item.getAfterSaleStatus());
                        //售后中的订单
                        List<AfterSale> afterlisting = CollUtil.isNotEmpty(afterSaleingMap) ? afterSaleingMap.get(item.getSn()) : null;
                        //售后退款订单
                        List<AfterSale> afterSaleFinis = CollUtil.isNotEmpty(afterSaleFinishMap) ? afterSaleFinishMap.get(item.getSn()) : null;
                        //已完成，但售后订单金额计算
                        if (isAfterSale && (alreadyApplied || afterSale || CollUtil.isNotEmpty(afterSaleFinis) || CollUtil.isNotEmpty(afterlisting))) {
                            if (returnAfter != null && returnAfter) {
//                                OrderFlow flow = new OrderFlow();
//                                for (OrderFlow orderFlow : orderFlowList) {
//                                    if (orderFlow.getOrderSn().equals(item.getOrderSn())) {
//                                        //获取退款多少金额
//                                        flow = orderFlow;
//                                        break;
//                                    }
//                                }
                                //-------------------------------------成本x数量
//                             totalAmount = totalAmount.add(isCost ? (item.getCostPrice() != null ? BigDecimal.valueOf(item.getCostPrice()).multiply(new BigDecimal(item.getNum())) : BigDecimal.ZERO) :  (flow.getRefundPrice() != null ? BigDecimal.valueOf(flow.getRefundPrice()) : BigDecimal.ZERO));

                                //累加afterSaleFinis中的actualRefundPrice 累计退款金额
                                //累加完成售后的实际退款金额
                                if (CollUtil.isEmpty(afterSaleFinis)) {
                                    continue;
                                }
                                totalAmount = totalAmount.add(afterSaleFinis.stream().map(afterSa -> BigDecimal.valueOf(afterSa.getActualRefundPrice())).reduce(BigDecimal.ZERO, BigDecimal::add));
                            } else {
                                //-------------------------------------成本x数量
                                //totalAmount = totalAmount.add(isCost ? (item.getCostPrice() != null ? BigDecimal.valueOf(item.getCostPrice()).multiply(new BigDecimal(item.getNum())) : BigDecimal.ZERO) :  (item.getFlowPrice() != null ? BigDecimal.valueOf(item.getFlowPrice()) : BigDecimal.ZERO));
                                //累加申请中的售后订单 申请售后的金额
                                totalAmount = totalAmount.add(isCost ? (item.getCostPrice() != null ? BigDecimal.valueOf(item.getCostPrice()) : BigDecimal.ZERO) : CollUtil.isEmpty(afterlisting) ? BigDecimal.ZERO : afterlisting.stream().map(afterSa -> BigDecimal.valueOf(afterSa.getApplyRefundPrice())).reduce(BigDecimal.ZERO, BigDecimal::add));
                                //再累加售后退款完成的订单
                                totalAmount = totalAmount.add(isCost ? (item.getCostPrice() != null ? BigDecimal.valueOf(item.getCostPrice()) : BigDecimal.ZERO) : CollUtil.isEmpty(afterSaleFinis) ? BigDecimal.ZERO : afterSaleFinis.stream().map(afterSa -> BigDecimal.valueOf(afterSa.getApplyRefundPrice())).reduce(BigDecimal.ZERO, BigDecimal::add));
                            }
                        }
                        //已完成，订单金额计算,无售后
                        if (!isAfterSale && !(alreadyApplied || afterSale) && CollUtil.isEmpty(afterSaleFinis) && CollUtil.isEmpty(afterlisting)) {
                            //-------------------------------------成本x数量
                            totalAmount = totalAmount.add(isCost ? (item.getCostPrice() != null ? BigDecimal.valueOf(item.getCostPrice()).multiply(new BigDecimal(item.getNum())) : BigDecimal.ZERO) : (item.getFlowPrice() != null ? BigDecimal.valueOf(item.getFlowPrice()) : BigDecimal.ZERO));
                        }
                    }
                }
            }
        }
        return totalAmount;
    }


    /**
     * 礼包订单列表
     * @param dto
     * @return
     */
    @Override
    public Page<OrderVO> getPackGiftOrderList(OrderDTO dto) {
        Page<OrderVO> orderVOPage = baseMapper.getPackGiftOrderList(new Page(dto.getPageNumber(), dto.getPageSize()), dto);
        return orderVOPage;
    }

    /**
     * 数据统计
     *
     * @param type 1日， 2周， 3月， 4季度
     */
    @Override
    public ResultMessage<Object> dataAnalysis(String scene, Integer type) {
        //获取查询的时间范围数据
        DataAnalysisParams dataAnalysisParams = this.getDataAnalysisParams(type);

        //统计数据
        DataStatisticsResult currentAnalysis = this.dataStatistics(scene, dataAnalysisParams.getCurrentStartDate(), dataAnalysisParams.getCurrentEndDate(),false);
        DataStatisticsResult previousAnalysis = this.dataStatistics(scene, dataAnalysisParams.getPreviousStartDate(), dataAnalysisParams.getPreviousEndDate(),false);

        //获取结果集
        DataAnalysisResult dataAnalysisResult = this.getDataAnalysisResult(currentAnalysis, previousAnalysis);
        log.info("dataAnalysisResult  == {}", JSONObject.toJSONString(dataAnalysisResult));
        return ResultUtil.data(dataAnalysisResult);
    }

    /**
     * 设置结果集
     */
    private DataAnalysisResult getDataAnalysisResult(DataStatisticsResult currentAnalysis, DataStatisticsResult previousAnalysis) {
        DataAnalysisResult result = new DataAnalysisResult();
        //当前周期有效数据
        DataStatisticsTableVO currentValidData = currentAnalysis.getValidDataStatistics();
        //上一个周期有效数据
        DataStatisticsTableVO previousValidData = previousAnalysis.getValidDataStatistics();
        log.info("currentValidData == {} , \n previousValidData == {}", JSONObject.toJSONString(currentValidData) , JSONObject.toJSONString(previousValidData));

        //有效订单数量
        DataAnalysisVO validOrderQuantity = new DataAnalysisVO();
        validOrderQuantity.setCurrent(currentValidData.getCount());
        validOrderQuantity.setPrevious(previousValidData.getCount());
        validOrderQuantity.setIncrease(this.getIncrease(currentValidData.getCount(), previousValidData.getCount()));
        result.setValidOrderQuantity(validOrderQuantity);

        //有效订单金额
        DataAnalysisVO validOrderAmount = new DataAnalysisVO();
        validOrderAmount.setCurrent(currentValidData.getOrderAmount());
        validOrderAmount.setPrevious(previousValidData.getOrderAmount());
        validOrderAmount.setIncrease(this.getIncrease(currentValidData.getOrderAmount(), previousValidData.getOrderAmount()));
        result.setValidOrderAmount(validOrderAmount);

        //有效订单成本支出
        DataAnalysisVO validOrderCostOutlay = new DataAnalysisVO();
        validOrderCostOutlay.setCurrent(currentValidData.getOrderCost());
        validOrderCostOutlay.setPrevious(previousValidData.getOrderCost());
        validOrderCostOutlay.setIncrease(this.getIncrease(currentValidData.getOrderCost(), previousValidData.getOrderCost()));
        result.setValidOrderCostOutlay(validOrderCostOutlay);

        //有效订单佣金支出
        DataAnalysisVO validOrderCommission = new DataAnalysisVO();
        validOrderCommission.setCurrent(currentValidData.getApportion());
        validOrderCommission.setPrevious(previousValidData.getApportion());
        validOrderCommission.setIncrease(this.getIncrease(currentValidData.getApportion(), previousValidData.getApportion()));
        result.setValidOrderCommission(validOrderCommission);

        //有效订单净利润
        DataAnalysisVO validOrderNetProfit = new DataAnalysisVO();
        validOrderNetProfit.setCurrent(currentValidData.getNetProfit());
        validOrderNetProfit.setPrevious(previousValidData.getNetProfit());
        validOrderNetProfit.setIncrease(this.getIncrease(currentValidData.getNetProfit(), previousValidData.getNetProfit()));
        result.setValidOrderNetProfit(validOrderNetProfit);

        return result;
    }

    /**
     * 计算增长比例 = (当前周期数据 - 上一个周期数据) / 上一个周期数据 * 100
     * @param currentData 当前周期数据
     * @param previousData 上一个周期数据
     * @return 增长比例
     */
    private BigDecimal getIncrease(BigDecimal currentData, BigDecimal previousData) {
        if (previousData.compareTo(BigDecimal.ZERO) == 0) {
            // 上一个周期数据为零，返回 当前周期数据 * 100
            return currentData.multiply(BigDecimal.valueOf(100));
        }
        BigDecimal res = currentData.subtract(previousData)
                .divide(previousData, 2, RoundingMode.HALF_UP)
                .multiply(BigDecimal.valueOf(100));
        return res.compareTo(BigDecimal.ZERO) > 0 ? res : BigDecimal.ZERO;
    }

    /**
     * 获取查询时间范围
     * @param type 统计周期类型：1日，2周，3月，4季度
     * @return 时间范围数据
     */
    private DataAnalysisParams getDataAnalysisParamsOld(Integer type) {
        DataAnalysisParams result = new DataAnalysisParams();
        if (type == null) {
            type = 1;
        }
        LocalDate today = LocalDate.now();
        // 今日
        String currentStartDate = "";
        String currentEndDate = "";
        String previousStartDate = "";
        String previousEndDate = "";
        //日
        if (type == 1) {
            currentStartDate = today + " 00:00:00";
            currentEndDate = today + " 23:59:59";
            previousStartDate =  today.minusDays(1) + " 00:00:00";
            previousEndDate = today.minusDays(1) + " 23:59:59";
        }
        //周
        if (type == 2) {
            currentStartDate = today.with(TemporalAdjusters.previousOrSame(java.time.DayOfWeek.MONDAY)) + " 00:00:00";
            currentEndDate = today.with(TemporalAdjusters.nextOrSame(java.time.DayOfWeek.SUNDAY)) + " 23:59:59";
            previousStartDate = today.minusWeeks(1).with(TemporalAdjusters.previousOrSame(java.time.DayOfWeek.MONDAY)) + " 00:00:00";
            previousEndDate =  today.minusWeeks(1).with(TemporalAdjusters.nextOrSame(java.time.DayOfWeek.SUNDAY)) + " 23:59:59";
        }
        //月
        if (type == 3) {
            LocalDate previousMonth = today.minusMonths(1);
            currentStartDate = today.with(TemporalAdjusters.firstDayOfMonth()) + " 00:00:00";
            currentEndDate = today.with(TemporalAdjusters.lastDayOfMonth()) + " 23:59:59";
            previousStartDate = previousMonth.with(TemporalAdjusters.firstDayOfMonth()) + " 00:00:00";
            previousEndDate = previousMonth.with(TemporalAdjusters.lastDayOfMonth()) + " 23:59:59";
        }
        //季度
        if (type == 4) {
            LocalDate previousQuarter = today.minusMonths(3);
            LocalDate firstDayOfPreviousQuarter = previousQuarter.with(previousQuarter.getMonth().firstMonthOfQuarter()).with(TemporalAdjusters.firstDayOfMonth());
            currentStartDate = today.with(today.getMonth().firstMonthOfQuarter()).with(TemporalAdjusters.firstDayOfMonth()) + " 00:00:00";
            currentEndDate = today.with(today.getMonth().firstMonthOfQuarter()).plusMonths(2).with(TemporalAdjusters.lastDayOfMonth()) + " 23:59:59";
            previousStartDate = firstDayOfPreviousQuarter + " 00:00:00";
            previousEndDate = firstDayOfPreviousQuarter.plusMonths(2).with(TemporalAdjusters.lastDayOfMonth()) + " 23:59:59";
        }
        result.setCurrentStartDate(currentStartDate);
        result.setCurrentEndDate(currentEndDate);
        result.setPreviousStartDate(previousStartDate);
        result.setPreviousEndDate(previousEndDate);

        log.info("getDataAnalysisResult == {}", JSONObject.toJSONString(result));
        return result;
    }

    private DataAnalysisParams getDataAnalysisParams(Integer type) {
        DataAnalysisParams result = new DataAnalysisParams();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        if (type == null) {
            type = 1;
        }
        LocalDate today = LocalDate.now();
        // 今日
        String currentStartDate = "";
        String currentEndDate = "";
        String previousStartDate = "";
        String previousEndDate = "";
        //日
        if (type == 1) {
            currentStartDate = today.format(formatter);
            currentEndDate = today.format(formatter);
            previousStartDate =  today.minusDays(1).format(formatter);
            previousEndDate = today.minusDays(1).format(formatter);
        }
        //周
        if (type == 2) {
            currentStartDate = today.with(TemporalAdjusters.previousOrSame(java.time.DayOfWeek.MONDAY)).format(formatter);
            currentEndDate = today.with(TemporalAdjusters.nextOrSame(java.time.DayOfWeek.SUNDAY)).format(formatter);
            previousStartDate = today.minusWeeks(1).with(TemporalAdjusters.previousOrSame(java.time.DayOfWeek.MONDAY)).format(formatter);
            previousEndDate =  today.minusWeeks(1).with(TemporalAdjusters.nextOrSame(java.time.DayOfWeek.SUNDAY)).format(formatter);
        }
        //月
        if (type == 3) {
            LocalDate previousMonth = today.minusMonths(1);
            currentStartDate = today.with(TemporalAdjusters.firstDayOfMonth()).format(formatter);
            currentEndDate = today.with(TemporalAdjusters.lastDayOfMonth()).format(formatter);
            previousStartDate = previousMonth.with(TemporalAdjusters.firstDayOfMonth()).format(formatter);
            previousEndDate = previousMonth.with(TemporalAdjusters.lastDayOfMonth()).format(formatter);
        }
        //季度
        if (type == 4) {
            LocalDate previousQuarter = today.minusMonths(3);
            LocalDate firstDayOfPreviousQuarter = previousQuarter.with(previousQuarter.getMonth().firstMonthOfQuarter()).with(TemporalAdjusters.firstDayOfMonth());
            currentStartDate = today.with(today.getMonth().firstMonthOfQuarter()).with(TemporalAdjusters.firstDayOfMonth()).format(formatter);
            currentEndDate = today.with(today.getMonth().firstMonthOfQuarter()).plusMonths(2).with(TemporalAdjusters.lastDayOfMonth()).format(formatter);
            previousStartDate = firstDayOfPreviousQuarter.format(formatter);
            previousEndDate = firstDayOfPreviousQuarter.plusMonths(2).with(TemporalAdjusters.lastDayOfMonth()).format(formatter);
        }
        result.setCurrentStartDate(currentStartDate);
        result.setCurrentEndDate(currentEndDate);
        result.setPreviousStartDate(previousStartDate);
        result.setPreviousEndDate(previousEndDate);

        log.info("getDataAnalysisResult == {}", JSONObject.toJSONString(result));
        return result;
    }


    /**
     * 根据订单号获取礼包订单的类型
     * @param orderSns
     * @return
     */
    @Override
    public List<OrderPackVO> getOrderPackInfoByOrderSn(String orderSns) {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
           log.info("#getOrderPackInfoByOrderSn# 休眠失败,正常往下走查询数据");
        }
        List<OrderPackVO> vos = new ArrayList<>();
        String[] orderSnArray = orderSns.split(",");
        log.info("#getOrderPackInfoByOrderSn#  orderSnArray:{}", JSONObject.toJSONString(orderSnArray));
        for (String orderSn : orderSnArray){
            Object storeObj = cache.get("store" + orderSn);
            Object plusObj = cache.get("plus" + orderSn);
//            if (storeObj == null && plusObj == null) {
//                return new ArrayList<>();
//            }

            if (storeObj != null) {
                log.info("#getOrderPackInfoByOrderSn#  orderSn:{},storeObj:{}", orderSn, JSONObject.toJSONString(storeObj));
                vos.add(JSONObject.parseObject(storeObj.toString(), OrderPackVO.class));
            }
            if (storeObj == null && plusObj != null) {
                log.info("#getOrderPackInfoByOrderSn#  orderSn:{},storeObj:{}", orderSn, JSONObject.toJSONString(plusObj));
                vos.add(JSONObject.parseObject(plusObj.toString(), OrderPackVO.class));
            }
        }
        return vos;
    }

    /**
     * 根据身份证号码查询免税订单号
     * @param dto
     * @return
     */
    @Override
    public Double sumTotalFreeTaxOrder(OrderDTO dto) {
        Double total = baseMapper.sumTotalFreeTaxOrder(dto);
        return total;
    }


    /**
     *
     * 1.查询是壹邦玖供应链在处理流程中的商品
     * 2.对比数据状态
     * 3.状态不匹配时,   选择处理方式
     */
    @Override
    public void syncSupplyChain() {
        LambdaQueryWrapper<Order> orderLambdaQueryWrapper =  new LambdaQueryWrapper<>();
//        UNDELIVERED DELIVERED SUBJECT_TO_SALE
        orderLambdaQueryWrapper.in(Order::getOrderStatus,
                OrderStatusEnum.UNDELIVERED.name(),
                OrderStatusEnum.DELIVERED.name(),
                OrderStatusEnum.SUBJECT_TO_SALE.name());
        List<Order> orderList = super.list(orderLambdaQueryWrapper);
        log.info("orderList = {}", JSONObject.toJSONString(orderList));
        if (CollectionUtil.isEmpty(orderList)) {
            return;
        }
        List<String> snList = orderList.stream().map(Order::getSn).toList();
        LambdaQueryWrapper<OrderItem> orderItemLambdaQueryWrapper = new LambdaQueryWrapper<OrderItem>();
        orderItemLambdaQueryWrapper.in(OrderItem::getOrderSn, snList);
        orderItemLambdaQueryWrapper.isNotNull(OrderItem::getSupplyChainOrderId);
        List<OrderItem> orderItemList = orderItemService.list(orderItemLambdaQueryWrapper);
        log.info("orderItemList = {}", JSONObject.toJSONString(orderItemList));
        if (CollectionUtil.isEmpty(orderItemList)) {
            return;
        }
        Map<String, List<Order>> listMap = orderList.stream().collect(Collectors.groupingBy(Order::getSn));
        orderItemList.parallelStream().forEach(orderItem -> {
            JSONObject jsonObject = this.orderDetailByThirdOrderSn(orderItem.getSn());
            log.info("syncSupplyChain jsonObject = {}", jsonObject.toJSONString());
            if (jsonObject.getInteger("code") == 0) {
                JSONObject data = jsonObject.getJSONObject("data");
                JSONArray read = data.getJSONArray("read");
                for (int i = 0; i < read.size(); i++) {
                    JSONObject object = read.getJSONObject(i);
                    System.out.println("object.toJSONString() = " + object.toJSONString());
                    //0待支付 1待发货 2待收货 3已完成，-1已关闭 5退换货 6已退款
                    Integer status = object.getInteger("status");
                    JSONArray orderItemsJson = object.getJSONArray("order_items");
                    Integer skuId = orderItemsJson.getJSONObject(0).getInteger("sku_id");
                    System.out.println("status = " + status);
                    List<Order> orders = listMap.get(orderItem.getOrderSn());
                    if (CollectionUtil.isEmpty(orders)) {
                        continue;
                    }
                    Order order = orders.get(0);
                    /**
                         0待支付 1待发货 2待收货 3已完成，-1已关闭 5退换货 6已退款
                         UNPAID("未付款"),
                         PAID("已付款"),
                         PLATFORM_PAID("待抵扣f分"),
                         UNDELIVERED("待发货"),
                         DELIVERED("已发货"),
                         OVERVIEW("已揽件"),
                         COMPLETED("已完成"),
                         STAY_PICKED_UP("待自提"),
                         SUBJECT_TO_SALE("待售后"),
                        TAKE("待核验"),
                        CANCELLED_LODING("取消中"),
                        CANCELLED("已取消");
                     */
//                    if (status == 0 && !order.getOrderStatus().equals(OrderStatusEnum.UNPAID.name())) {
//                        //待支付
//                        this.callback();
//                        continue;
//                    }
                    CallBackVO callBackVO = new CallBackVO();
                    callBackVO.setOrder_sn(orderItem.getSn());
                    callBackVO.setProduct_id(String.valueOf(skuId));
                    callBackVO.setOrder_item_id(orderItem.getSupplyChainOrderId());
//                    if (status == 1 && !order.getOrderStatus().equals(OrderStatusEnum.UNDELIVERED.name())) {
//                        //待发货
//                        this.callback(callBackVO);
//                        continue;
//                    }
//                    if (status == 2 && !order.getOrderStatus().equals(OrderStatusEnum.DELIVERED.name())) {
//                        //待收货
//                        this.callback(callBackVO);
//                        continue;
//                    }
//                    if (status == 3  && !order.getOrderStatus().equals(OrderStatusEnum.COMPLETED.name())) {
//                        //已完成
//                        this.callback(callBackVO);
//                        continue;
//                    }
                    if (status == -1 && !order.getOrderStatus().equals(OrderStatusEnum.CANCELLED.name())) {
                        //已关闭
                        callBackVO.setMessage_type("after_sales.complete");
                        this.callback(callBackVO);
                        continue;
                    }
                    if (status == 6 && !order.getOrderStatus().equals(OrderStatusEnum.CANCELLED.name())) {
                        //已退款
                        callBackVO.setMessage_type("after_sales.complete");
                        this.callback(callBackVO);
                        continue;
                    }
                }
            }
        });
    }

//    public static void main(String[] args) {
////        String token = this.getToken();
//        String tokenUrl = "https://supply.yibangjiu.com/supplyapi" + "/app/application/getToken";
//        Map<String, Object> params = new HashMap<>();
//        params.put("app_key", "application4");
//        params.put("app_secret", "a7c5dbc8aaa6a67bc2a73b1d71faeb91");
//        HttpRequest post1 = HttpUtil.createPost(tokenUrl).body(JSONObject.toJSONString(params));
//        String body = post1.execute().body();
//        JSONObject jsonObject = JSONObject.parseObject(body);
//        if (jsonObject.getInteger("code") != 0) {
//            throw new ServiceException("token获取失败");
//        }
////        redisTemplate.boundValueOps("yunxin_token").set(jsonObject.getJSONObject("data").getString("token"));
////        redisTemplate.expire("yunxin_token", 30, TimeUnit.MINUTES);
//        String token = jsonObject.getJSONObject("data").getString("token");
//
//        HttpRequest httpRequest = HttpUtil.createGet("https://supply.yibangjiu.com/supplyapi" + "/app/order/orderDetailByThirdOrderSn?third_order_sn=OI202405081788017749310889984").header("x-token", token);
//        String body2 = httpRequest.execute().body();
//        JSONObject jsonObject2 = JSONObject.parseObject(body2);
//
//        log.info("syncSupplyChain jsonObject = {}", jsonObject2.toJSONString());
//        if (jsonObject2.getInteger("code") == 0) {
//            JSONObject data = jsonObject2.getJSONObject("data");
//            JSONArray read = data.getJSONArray("read");
//            for (int i = 0; i < read.size(); i++) {
//                JSONObject object = read.getJSONObject(i);
//                System.out.println("object.toJSONString() = " + object.toJSONString());
//                Integer status = object.getInteger("status");
//                System.out.println("status = " + status);
//
//                JSONArray orderItemsJson = object.getJSONArray("order_items");
//                Integer skuId = orderItemsJson.getJSONObject(0).getInteger("sku_id");
//                System.out.println("skuId = " + skuId);
//            }
//        }
//    }
}